2010-11-18 4 views
2

Ich habe ein bisschen eine Sackgasse in versucht, diese herauszufinden ... Verwenden Sie das MVVM-Muster in WPF, unser C# -Modell feuert ein Ereignis ab, um zu sagen, dass etwas passiert ist. Ich möchte in der Lage sein, dieses Ereignis in meinem ViewModel zu behandeln und dann entweder ein Storyboard zu kicken oder die Sichtbarkeit eines versteckten Panels auf der aktuellen Xaml-Seite zu ändern. Dies muss ohne Code behangen werden.WPF: Wie handle ich ein Ereignis von einem Modell zur dynamischen Aktualisierung XAML in MVVM

Ich kann für das Ereignis in meinem ViewModel synchronisieren, eine Eigenschaft aktualisieren, um zu sagen, wie der Name des Ereignisses lautet, und eine NotifyPropertyChanged auslösen, aber wie bekomme ich das, um ein Storyboard zu starten oder zu einem Boolean zu true/false in der Visibility-Eigenschaft meines Grids? Die Eigenschaft, die ich an hs anschließe, um der Ereignisname zu sein, da verschiedene Grids basierend auf verschiedenen Ereignissen gezeigt werden können, so dass ich eine Art der Zuordnung zu einem booleschen Wert benötige. Die ideale Lösung wäre jedoch, ein Storyboard zu starten. Ich habe DataTriggers betrachtet, aber sie scheinen alle mit Stilen verknüpft zu sein und nicht mit tatsächlichen Seiten.

Irgendwelche Ideen, wie ich das erreichen kann?

Danke!

Antwort

0

Binden Sie die Visibility-Eigenschaft in Ihrem Grid in Xaml an die boolesche Eigenschaft in Ihrem ViewModel.

Jetzt tun Sie, was Sie in Ihrem ViewModel benötigen, und legen Sie die Eigenschaft fest. Solange es INotifyPropertyChanged oder eine DependencyProperty ist, wird es funktionieren.

Ich müsste mehr graben, um herauszufinden, wie man ein Storyboard startet, aber ich habe keinen Zweifel, es wäre fast so einfach. Storyboards können auch von PropertyTriggers gestartet werden, glaube ich. Ich werde das hier lassen, um dich anzufangen.

+0

Danke für die Antwort Dave - wirklich zu schätzen! Problem ist, dass diese Eigenschaft kein Bool ist. Es ist eine Schnur. Im Grunde gibt es eine ganze Reihe von Ereignissen, die auftreten können (hunderte tatsächlich!), Also denke ich eher an die Zeilen, diese etwas zu tippen und den Xaml irgendeine Art von tun zu lassen: also der Ausdruck wird als wahr ausgewertet und dies setzt die Sichtbarkeit auf wahr ... – Slippy

+0

Sichtbarkeit hat 3 mögliche Werte, Sie benötigen einen Konverter, um es an einen Booleschen Wert zu binden und wählen Sie, was wahr/falsch ist bedeutet für Collapsed/Versteckt/Sichtbar. – Matthieu

+0

Prost Matthieu - Ich hatte gehofft, einen Konverter zu vermeiden, da ich eine endlose unbegrenzte Liste von Ereignissen habe. Ich denke, Konverter müssen verwendet werden, wenn Sie eine Expression Evaluation durchführen wollen? – Slippy

1

ich dies habe in der Vergangenheit verwendet, um ein Storyboard in Code-Behind-kick off

Storyboard animation = (Storyboard)this.FindResource("ShowPanelStoryboard"); 
animation.Begin(); 

Dieser Code geht hinter der Ansicht, nicht in dem Ansichtsmodell. Persönlich stört mich ein Code hinter meiner Ansicht nicht, es wird nur die Ansicht verwandt. In dem Projekt, in dem ich das verwendet habe, habe ich einen Listener zum VisibilityChanged Event hinzugefügt und als es in Visible geändert wurde, habe ich das Storyboard ausgeführt.

Als Ihr Pop-up für die Ansicht, es gibt ein paar Möglichkeiten. Einer meiner Favoriten war gerade das Hinzufügen einer IsPopupShown Eigenschaft auf das Ansichtsmodell, die Bindung an mich meine Platte Sichtbarkeit und es wahr jederzeit Einstellung der Popup angezeigt werden soll. Das ViewModel behandelt dann die Ereignisse, die das angezeigte Popup auslösen oder nicht.

Eine Alternative, wie Dave White vorgeschlagen ist, einen Konverter zu verwenden. Wenn Ihr Wert nicht immer wahr/falsch ist, können Sie einen Konverter erstellen, der überprüft, ob ein gebundener Wert dem ConverterParameter entspricht, und einen Visibility-Wert zurückgeben.

+0

Danke Rachel - das einzige Problem, das ich hier habe, ist, dass ich überhaupt keinen Code habe. Ich arbeite nur mit Loose Xaml :(Ich werde vielleicht einen Blick auf die Converter-Route werfen, um zu sehen, ob das funktioniert. Danke für die Antwort. Wirklich zu schätzen! – Slippy

1

Von Ihrem Kommentar, es scheint mir, wie Sie möchten, ist eine Event Eigenschaft des Typs object in Ihrem Ansichtsmodell zu exponieren. Wenn das Ansichtsmodell ein Ereignis empfängt, setzt es Event auf ein Objekt eines für dieses Ereignis geeigneten Typs. In XAML, haben Sie dies:

<ContentControl Content="{Binding Event}"/> 

und im Ressourcenverzeichnis ein DataTemplate für jeden bestimmten Ereignistyp definieren Sie anzeigen möchten. Wenn Event null ist, wird nichts angezeigt. Wenn Event ein Objekt enthält, das Sie eine DataTemplate für definiert haben, wird es angezeigt, dass die Vorlage.

Ja, Sie müssen für jeden Ereignistyp eine Klasse erstellen (falls Sie noch keine haben).

Ein anderer Weg ist des armen Mannes Template Wähler zu implementieren:

<TextBlock Text="This is displayed if Foo contains 'BAR'"> 
    <TextBlock.Style> 
     <Style TargetType="TextBlock"> 
     <Setter Property="Visibility" Value="Collapsed"/> 
     <Style.Triggers> 
      <DataTrigger Property="Foo" Value="BAR"> 
       <Setter Property="Visibility" Value="Visible"/> 
      </DataTrigger> 
     </Style.Triggers> 
     </Style> 
    </TextBlock.Style> 
</TextBlock> 
<TextBlock Text="This is displayed if Foo contains 'BAZ'"> 
    <TextBlock.Style> 
     <Style TargetType="TextBlock"> 
     <Setter Property="Visibility" Value="Collapsed"/> 
     <Style.Triggers> 
      <DataTrigger Property="Foo" Value="BAZ"> 
       <Setter Property="Visibility" Value="Visible"/> 
      </DataTrigger> 
     </Style.Triggers> 
     </Style> 
    </TextBlock.Style> 
</TextBlock> 

Es ist eine Art dummerweise ausführlich, aber es ist eine einfache Möglichkeit, die Handhabung viel gegenseitig ausschließenden Anzeigeoptionen.

+0

Danke Robert - das klingt total machbar. Ich werde arbeiten durch das Beispiel, um zu sehen, ob es den Trick macht. Danke für die Antwort! – Slippy