Domanda

Così sto imparando WPF in questo momento, e voglio fare un semplice DataBind tra un valore bool, e se un MenuItem è abilitato o meno.

ho codificato in questo modo:

<MenuItem Name="miSaveFile" Header="Save" Click="miSaveFile_Click"
IsEnabled="{Binding}" />

E nel file .cs ho impostato:

miSaveFile.DataContext = dataChanged;

Per qualche motivo il MenuItem non sembra essere adeguatamente riflettere lo stato di DataChanged.

Che cosa mi manca?

È stato utile?

Soluzione

Si sta meglio il legame con un oggetto piuttosto che un tipo primitivo. Questo oggetto è spesso definito come il "modello" per la visualizzazione.

WPF utilizza l'interfaccia INotifyPropertyChanged per il modello (o spesso vista del modello) per notificare la vista che il modello è cambiato Uniti.

Quindi, per prima cosa vuole definire una classe di dati come il modello che implementa l'interfaccia INotifyPropertyChanged e genera l'evento PropertyChanged ogni volta che una proprietà viene modificata.

Quando si imposta un legame, si dispone di 5 elementi principali sul legame di cui preoccuparsi. Il legame ha un oggetto di origine, un percorso di origine sull'oggetto di origine, un oggetto di destinazione, una proprietà target sull'oggetto bersaglio, e un convertitore opzionale.

Se non si specifica la fonte, il valore predefinito è il DataContext del controllo del binding è impostato su. Ci sono altre opzioni per impostare la fonte. Qui è un articolo di Microsoft su come impostare la fonte. È quindi possibile impostare il percorso di una proprietà di tirare fuori la fonte per l'associazione. Nel tuo caso, la fonte è un valore booleano e non v'è alcun percorso, perché il legame è con l'intero oggetto di origine.

L'obiettivo è sempre il controllo che si imposta il legame, e la proprietà target è la proprietà di questo controllo che si sta associando a. In questo caso, Menultem e IsEnabled.

Un convertitore può opzionalmente convertire il valore di origine in un valore compatibile con la proprietà target. È possibile utilizzare qualsiasi oggetto per un convertitore che implementa IValueConverter o IMultiValueConverter (per MutliBindings).

Nel tuo caso, vorrei innanzitutto creare un modello che implementa INotifyPropertyChanged. Avanti, vorrei assegnare i DataContext del menu a un'istanza del modello. Poi vorrei impostare il legame:

IsEnabled="{Binding Path=EnableFlag}"

(dove EnableFlag è una proprietà booleana nel modello che si desidera al menu di legarsi a)

Se si imposta l'interfaccia INotifyPropertyChanged correttamente, la voce di menu sarà attivata / disattivata ogni volta che si modifica questa proprietà sul modello.

Altri suggerimenti

Per un MenuItem, non sarebbe un approccio migliore per utilizzare il modello di comando, piuttosto che fare clic e proprietà IsEnabled?

Dopo InitialiseComponent ():

this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save, fileSaveExecuted, fileSaveCanExecute));

Metodi aggiuntivi:

/* here is where you set e.CanExecute true for enabled: */
    private void fileSaveCanExecute(object x, CanExecuteRoutedCommandEventArgs e)) { e.CanExecute = ...; e.Handled = true; }
/* here is where you act on the command: */
    private void fileSaveExecuted(object sender, ExecutedRoutedEventArgs e) { ... }

XAML:

<MenuItem Header="_Save" Command="Save"/>

In che modo l'interfaccia utente sa quando la variabile DataChanged ha effettivamente cambiato?

Io di solito si legano a una proprietà su un oggetto, e lasciare che la classe implementa INotifyPropertyChanged. L'interfaccia utente è quindi "automagicamente" aggiornata ogni volta che viene richiamato l'evento PropertyChanged.

Così avrei

<MenuItem Name="miSaveFile" Header="Save" Click="miSaveFile_Click"
IsEnabled="{Binding DataChanged}"</MenuItem>

e quindi impostare miSaveFile.DataContext = myObject.DataChanged (MyObject può essere presente se si utilizza il codebehind)

Edit: Ho appena fatto un test rapido. Se si imposta il contesto dati direttamente alla struttura DataChanged, non viene aggiunta una sottoscrizione per l'evento PropertyChanged sull'oggetto proprietario. Ma la soluzione suggerisco lavori.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top