2017-12-09 2 views
-3

Ich habe eine Klasse mit dem Namen osmAppBarButton, die von AppBarButton (UWP) erbt, zu dem ich eine Abhängigkeitseigenschaft namens ButtonState hinzugefügt habe. (Enum Normal, Dim, Hell, Flash)Probleme mit MVVM

Ich habe einen Style für alle meine osmAppBarButtons verwendet, die einen DataTriggerBehavior verwendet, um den ButtonState zu überprüfen und den entsprechenden VisualState auszuwählen.

Ich war ziemlich zufrieden mit mir selbst, da DPs und der VisualStateManager sind alle neu für mich. Dann traf ich ein Problem ..

Wie kann ich einen ButtonState von OsmAppBarButton aus dem ViewModel ändern, ohne MVVM zu brechen? Ich dachte darüber nach, eine VM-Eigenschaft für den ButtonState jeder Schaltfläche in meiner Ansicht zu haben, aber das würde bedeuten, dass die VM etwas über die View wissen würde.

Ich denke, dass die Antwort mit Attached Behaviors liegen kann, aber ich habe kein passendes Beispiel gefunden.

Irgendwelche Ideen?

Antwort

0

Die Art, wie Sie Werte von einer Viewmodel-Eigenschaft in eine Abhängigkeitseigenschaft abrufen, besteht darin, eine Binding zu verwenden. Sicherlich kein angehängtes Verhalten; Ich bin sicher, dass Sie könnte finden Sie einen Weg, um das mit einem angehängten Verhalten zu tun, aber verwenden Sie einfach eine Binding. Das Ansichtsmodell muss INotifyPropertyChanged implementieren. Es muss der DataContext für die Ansicht sein, in der die Appbar-Schaltfläche lebt, und Sie dürfen sich nicht selbst in den Fuß schießen, indem Sie DataContext an etwas Zufälliges in einem Elternelement der Appbar-Schaltfläche binden.

Geben Sie dem Viewmodel eine öffentliche Eigenschaft, die PropertyChanged erhöht, wenn sich der Wert ändert. An diese Eigenschaft binden.

Ein Enum wie ButtonState mit Normal, Dim, Bright, Flash-Werte ist nicht die Art von was ein Viewmodel in einer "richtigen" MVVM-Implementierung beachten sollte. Das ist auch nicht wirklich ein dummer Punkt. Ich würde vorschlagen, dass das Viewmodel seinen Zustand durch Eigenschaften offen legt, die den Zustand des Viewmodels in seinen eigenen Bedingungen ausdrücken (ich könnte Ihnen ein Beispiel geben, wenn ich wüsste, was Sie hier machen). Vielleicht hat das Ansichtsmodell einen Zustand, der normal, beschäftigt, Fehler, wartend sein kann - diese können auf verschiedene ButtonState-Werte abbilden. "Error" ist ein Zustand des Viewmodels. "Flash" ist einer von vielen Möglichkeiten, wie eine Ansicht wählen kann, um einem Benutzer einen bestimmten Viewmodel-Status mitzuteilen.

Wenn das Viewmodel den relevanten Status mit einer oder mehreren Eigenschaften mit anderen Typen als ButtonState ausdrückt, würden Sie einen Konverter - vielleicht einen Multiconverter - schreiben, um all das in einen ButtonState Wert zu übersetzen.

Aber es wird nicht das Ende der Welt sein, wenn Ihr Lernprogramm ButtonState in einem Viewmodel verwendet, und das wird einfacher sein. So binden Sie es an diese:

private ButtonState _fooBarButtonState = ButtonState.ItsComplicated; 
public ButtonState FooBarButtonState { 
    get { return _fooBarButtonState; } 
    set { 
     if (value != _fooBarButtonState) { 
      _fooBarButtonState = value; 
      OnPropertyChanged(nameof(FooBarButtonState)); 
     } 
    } 
} 

XAML:

<local:osmAppBarButton 
    ButtonState="{Binding FooBarButtonState}" 
    /> 

Aber wenn Sie mit meinem Vorschlag gehen möchte einen anderen Zustand Enum im Ansichtsmodell zu verwenden, Konverter sind ziemlich trivial zu schreiben. Lassen Sie es mich wissen, wenn Sie einen Haken haben, aber wenn Sie eine Abhängigkeitseigenschaft haben und Viewstates funktioniert, werden Sie es bekommen.