Frage

Also ich WPF jetzt lerne, und möchte eine einfache databind zwischen einem Bool Wert tun, und ob ein MenuItem aktiviert ist oder nicht.

Ich habe es wie folgt codiert:

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

Und in der CS-Datei I gesetzt:

miSaveFile.DataContext = dataChanged;

Aus irgendeinem Grund die MenuItem scheint nicht richtig zu sein, den Zustand von datachanged widerspiegelt.

Was bin ich fehlt?

War es hilfreich?

Lösung

Sie sind besser dran, auf ein Objekt Bindung als auf eine primitive Art. Diese Aufgabe wird oft als das „Modell“ für Ihre Ansicht.

WPF verwendet die INotifyPropertyChanged-Schnittstelle für das Modell (oder oft sehen-Modell), um die Ansicht zu benachrichtigen, dass die Modellzustände geändert haben.

So erhalten Sie zunächst eine Datenklasse als das Modell definieren wollen, die die INotifyPropertyChanged-Schnittstelle implementiert und feuert das Property Ereignis, wenn eine Eigenschaft geändert wird.

Wenn Sie eine Bindung zu setzen, müssen Sie 5 Hauptelemente an der Bindung zu kümmern. Die Bindung hat eine Quellenobjekt, einen Source-Pfad auf dem Quellenobjekt, ein Zielobjekt, eine Zieleigenschaft auf dem Zielobjekt und einen optionalen Konverter.

Wenn Sie nicht die Quelle angeben, wird standardmäßig die Datacontext der Kontrolle der Bindung eingestellt auf. Es gibt andere Optionen für die Quelle einstellen. Hier ist ein Microsoft-Artikel zur Einstellung der Quelle. Anschließend können Sie den Pfad einer Eigenschaft für die Bindung aus der Quelle zu ziehen. In Ihrem Fall ist die Quelle ein boolean und es gibt keinen Weg, weil die Bindung unter Verwendung des gesamten Quellobjekt ist.

Das Ziel ist immer die Kontrolle, dass Sie die Bindung auf, und die Zieleigenschaft ist die Eigenschaft auf dieser Steuerung eingestellt, die Sie verbindlich sind. In diesem Fall MenuItem und IsEnabled.

A-Wandler kann optional den Quellwert in einen Wert konvertieren, die mit der Zieleigenschaft kompatibel ist. Sie können jedes Objekt für einen Konverter verwenden, die IValueConverter oder IMultiValueConverter (für MutliBindings) implementiert.

In Ihrem Fall würde ich zuerst ein Modell erstellen, das INotifyPropertyChanged implementiert. Als nächstes würde ich die Datacontext des Menüs auf eine Instanz des Modells zuordnen. Dann würde ich die Bindung an:

IsEnabled="{Binding Path=EnableFlag}"

(Wo EnableFlag ist eine boolesche Eigenschaft in dem Modell, das Sie zum Menü möge, binden)

Wenn Sie die INotifyPropertyChanged-Schnittstelle richtig eingerichtet ist, wird der Menüpunkt aktiviert / deaktiviert werden, wenn Sie diese Eigenschaft auf dem Modell ändern.

Andere Tipps

Für eine MenuItem, wäre es nicht ein besserer Ansatz sein, den Befehl Modell zu verwenden, anstatt Anweisungen und IsEnabled Eigenschaften?

Nach InitialiseComponent ():

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

Weitere Methoden:

/* 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"/>

Wie weiß der Benutzeroberfläche, wenn die datachanged Variable tatsächlich verändert hat?

Ich binde normalerweise auf eine Eigenschaft auf ein Objekt, und lassen Sie diese Klasse INotifyPropertyChanged implementieren. Die Benutzeroberfläche wird dann „automatisch“ aktualisiert, wenn das Property Ereignis aufgerufen wird.

Also ich würde

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

und stellen Sie dann miSaveFile.DataContext = myObject.DataChanged (MyObject kann das sein, wenn Sie den Code-Behind verwenden)

Edit: Ich habe gerade einen schnellen Test. Wenn Sie den Datenkontext direkt an die Datachanged-Eigenschaft wird ein Abonnement für das Property Ereignis auf dem Eigentümer-Objekt hinzugefügt. Aber die Lösung schlage ich vor, funktioniert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top