C# WPF:如何处理模型中的事件以动态更新MVVM中的xaml

C# WPF:如何处理模型中的事件以动态更新MVVM中的xaml,c#,wpf,events,data-binding,mvvm,C#,Wpf,Events,Data Binding,Mvvm,我想弄明白这件事有点走投无路了。。。使用WPF中的MVVM模式,我们的C#模型触发一个事件来表示发生了什么。我希望能够在ViewModel中处理该事件,然后在当前Xaml页面上启动情节提要或更改隐藏面板的可见性。这必须在没有代码隐藏的情况下进行处理 我可以在我的ViewModel中同步事件,更新属性以说明该事件的名称,并触发NotifyPropertyChanged,但如何使其启动故事板或映射到网格可见性属性上的布尔真/假?我绑定到hs的属性是事件名称,因为不同的网格可能基于不同的事件显示,所以

我想弄明白这件事有点走投无路了。。。使用WPF中的MVVM模式,我们的C#模型触发一个事件来表示发生了什么。我希望能够在ViewModel中处理该事件,然后在当前Xaml页面上启动情节提要或更改隐藏面板的可见性。这必须在没有代码隐藏的情况下进行处理

我可以在我的ViewModel中同步事件,更新属性以说明该事件的名称,并触发NotifyPropertyChanged,但如何使其启动故事板或映射到网格可见性属性上的布尔真/假?我绑定到hs的属性是事件名称,因为不同的网格可能基于不同的事件显示,所以我需要一种将其映射到布尔值的方法。然而,理想的解决方案是启动一个故事板。我看过DataTriggers,但它们似乎都链接到样式,而不是实际页面

有什么办法可以做到这一点吗


谢谢

将网格上的可见性属性(Xaml)绑定到ViewModel上的布尔属性

<Grid Visibility="{Binding Path=VisiblePropertyOnViewModel}">

现在,在ViewModel中执行所需的操作并设置属性。只要它没有INotifyPropertyChanged或是DependencyProperty,它就会工作


我必须做更多的挖掘,以找出如何启动故事板,但我毫不怀疑,这将是几乎一样容易。我相信故事板也可以由房地产装配工来启动。我留下这个让你开始吧。

我过去用这个来启动代码隐藏中的故事板

Storyboard animation = (Storyboard)this.FindResource("ShowPanelStoryboard");
animation.Begin();
此代码位于视图后面,而不是在ViewModel中。就个人而言,我不介意视图背后的一些代码,只要它只与视图相关。在我使用它的项目中,我向
VisibilityChanged
事件添加了一个侦听器,当它变为Visible时,我运行了故事板

至于显示弹出窗口,有几种方法。我最喜欢的一个方法是在ViewModel中添加一个
ispopushown
属性,将面板的可见性绑定到它,并在弹出窗口显示时将其设置为true。然后,ViewModel处理触发弹出窗口是否显示的事件


建议的另一种选择是使用转换器。如果您的值不总是真/假,那么您可以创建一个转换器,检查绑定值是否等于ConverterParameter,并返回一个可见性值。

从您的注释中,我认为您可能需要做的是在视图模型中公开类型为
对象的
事件
属性。当视图模型接收到事件时,它会将
event
设置为适合该事件类型的对象。在XAML中,您有:

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

这有点愚蠢冗长,但这是处理许多互斥显示选项的简单方法。

谢谢你的回答Dave-非常感谢!问题是这个属性不是bool。这是一根绳子。基本上,可能会发生一大堆事件(实际上有数百个!),因此我在松散地键入这些事件并让Xaml执行某种操作时考虑更多:-因此表达式的计算结果为true,这将可见性设置为true…可见性有3个可能的值,您需要一个转换器将其绑定到布尔值,并选择true/false对于折叠/隐藏/可见的含义。干杯,Matthieu-我希望避免使用转换器,因为我有一个无限的事件列表。我想,如果要执行任何表达式计算,必须使用转换器?@Slippy-记住,您的ViewModel可以以任何需要的方式处理所有事件,然后将绑定到ViewModel的基于Xaml的可见性属性设置为Visibility枚举类型的属性。如果要将视图绑定到ViewModel属性,则不需要将视图绑定到模型触发的事件。感谢Dave-是的,我最初也这么想。但是我将如何识别该特定事件?如果我在系统中有大约100个事件,有没有办法避免写入我必须绑定到的大约100个可见性属性?如果eventA发生,我会显示GridA,如果EventB发生,显示GridB等等…谢谢罗伯特-这听起来完全可行。我将通过这个例子来了解它是否起作用。谢谢你的回答!谢谢Rachel-我这里唯一的问题是我根本没有代码落后。我纯粹是在使用松散的Xaml:(我可能会查看一下转换器路径,看看这是否有效。感谢您的回复。非常感谢!
<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>