2012-09-05 7 views
5

In un'applicazione WPF, sto creando una finestra di impostazione per personalizzare le scorciatoie da tastiera.Come cambio TextBox.Text senza perdere l'associazione in WPF?

Nelle caselle di testo, gestisco l'evento KeyDown e converto l'evento Key in un formato leggibile dall'uomo (e anche il modulo in cui desidero avere i miei dati).

La casella di testo viene dichiarato come questo

<TextBox Text="{Binding ShortCutText, Mode=TwoWay}"/> 

e nel gestore di eventi, ho provato utilizzando sia

(sender as TextBox).Text = "..."; 

e

(sender as TextBox).Clear(); 
(sender as TextBox).AppendText("..."); 

In entrambi i casi, il il binding a viewmodel non funziona, il viewmodel contiene ancora i vecchi dati e non viene aggiornato. Il binding nell'altra direzione (da viewmodel alla casella di testo) funziona correttamente.

C'è un modo per modificare TextBox.Text dal codice senza utilizzare l'associazione? Oppure c'è un errore da qualche altra parte nel mio processo?

+3

Idealmente si dovrebbe aggiornare questo valore nel modello che rifletterà automaticamente le modifiche nelle caselle di testo mentre si utilizza MVVM. – Deepesh

+1

Prova ad aggiungere "UpdateSourceTrigger = PropertyChanged" al tuo binding –

+0

So che questa è una vecchia domanda ormai ma una cosa che la gente sembra ignorare qui è se la proprietà di un controllo è legata ad un altro controllo (Pronunciare un elenco di caselle di controllo che sono tutti spuntati o deselezionati da una casella di controllo genitore). Potrebbe non esserci nulla nella VM per aiutarti qui. –

risposta

8
var box = sender as TextBox; 
// Change your box text.. 

box.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 

Questo dovrebbe forzare l'associazione a aggiornare.

+0

Con UpdateTarget(), in realtà non esegue alcun aggiornamento, anche la casella di testo mantiene il vecchio valore. –

+0

Alcune risposte per richiedere ancora un po 'di riflessione .. visto che hai usato lo stesso codice che ho fatto, tranne che non ho regolato il testo tra .. Ritengo che questa sia la risposta giusta? – KyorCode

+0

Ti ho dato un +1 visto che sei l'unico che ha aiutato. –

3

Non modificare la proprietà Text: modificare ciò a cui si sta vincolando.

+0

Perché la casella di testo dovrebbe avere un riferimento al viewmodel stesso? Non voglio fare alcun casting per il mio tipo specifico, questo è il motivo per cui ho usato il bending a due vie –

+0

Non dovrebbe, non fare riferimento alla casella di testo. devo aggiornare il testo, non dovrebbe conoscere la casella di testo –

+0

Seriamente? È un gestore di eventi "TextBoxInput (oggetto mittente, KeyEventArgs e)" ... –

1

Questo ha fatto il trucco:

private static void SetText(TextBox textBox, string text) 
    { 
     textBox.Clear(); 
     textBox.AppendText(text); 
     textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 
    } 
0

Non avete bisogno di modificare il valore di TextBox a tutti! Nel codice è necessario solo modificare il valore correlato (ShortCutText) È inoltre possibile impostare IsReadOnly = "True" proprietà del TextBox.

<TextBox Text="{Binding Path=ShortCutText,Mode=OneWay}" 
     KeyDown="TextBox_KeyDown" IsReadOnly="True"/> 

Si dovrebbe capire INotifyPropertyChanged interfaccia nella classe, come descritto in MSDN:

http://msdn.microsoft.com/library/system.componentmodel.inotifypropertychanged.aspx

Modifica setter della vostra ShortCutText proprietà (a cui il TextBox è destinato a) :

class MyClass:INotifyPropertyChanged 
{ 
    string shortCutText="Alt+A"; 
    public string ShortCutText 
    { 
     get { return shortCutText; } 
     set 
      { 
        shortCutText=value; 
        NotifyPropertyChanged("ShortCutText"); 
      } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    void NotifyPropertyChanged(string props) 
    { 
     if(PropertyChanged != null) 
      PropertyChanged(this , new PropertyChangedEventArgs(prop)); 
    } 

} 

WPF si iscriverà automaticamente all'evento PropertyChanged. Ora usare KeyDown caso di TextBox, ad esempio, in questo modo:

private void TextBox_KeyDown(object sender , KeyEventArgs e) 
{ 
    ShortCutText = 
     (e.KeyboardDevice.IsKeyDown(Key.LeftCtrl)? "Ctrl+ " : "") 
     + e.Key.ToString(); 
} 
1

Ho caso simile.

Quando si cancella la casella di testo questo perde il binding.

ho indossato: textbox1.Text = String.empty

cambio per questo: textbox1.Clear()

e questo è il punto di partenza per la mia soluzione

0

Se si sta utilizzando MVVM non è necessario modificare la proprietà Text del controllo TextBox dal codice , cambia il valore nel modello di vista e il modello farà il suo lavoro sincronizzando la vista.

Problemi correlati