我有一个主视图模型,并根据情况加载了一些用户控件(稳定性,坦克)。这些用户控件具有诸如StabilityVM,TankVM之类的视图模型。我的问题是如何将数据从主视图模型发送到用户控件视图模型,反之亦然。我的main.xaml及其视图模型如下所示
主窗口xaml部分
<ContentControl Grid.Row="1" Content="{Binding
ActiveUserControl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type vm:TankVM}">
<uc:Tank></uc:Tank>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StabilityVM}">
<uc:Stability></uc:Stability>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
主视图模型零件
public class MainVM : INotifyPropertyChanged
{
Stability stability;
Tank tank;
WeightItem weightItem;
public List<Grid> myControls = new List<Grid>();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private UserControl activeUserControl;
public UserControl ActiveUserControl
{
get { return activeUserControl; }
set { activeUserControl = value;
OnPropertyChanged(nameof(ActiveUserControl));
}
}
public MainVM()
{
//First user control class
stability = new Stability();
stability.Visibility = Visibility.Visible;
//Second user control class
tank = new Tank();
tank.Visibility = Visibility.Visible;
ActiveUserControl = stability;
ActiveUserControl.Visibility = Visibility.Visible;
}
}
答案 0 :(得分:0)
要在视图模型之间进行通信,可以使用mediator pattern。 Caliburn.Micro或Prism之类的许多WPF应用程序框架都提供了此模式的具体实现,因此您不必自己实现它。两者都提供了一个所谓的事件聚合器,用于通过松耦合事件进行通信。
例如,在Prism中,您将定义一个带有或不带有事件参数的事件类型。
// Events derive from PubSubEvent or PubSubEvent<T> if you use event aruments
public class TankChangedEvent : PubSubEvent<TankChangedEventArgs>
{
}
// Event arguments for the above event, uses a property to capture the changed tank
public class TankChangedEventArgs
{
public Tank Tank { get; }
TankChangedEventArgs(Tank tank)
{
Tank = tank;
}
}
然后在发送者视图模型中,使用事件聚合器发布事件。请注意,您需要创建或注入事件聚合器的实例eventAggregator
。
var args = new TankChangedEventArgs(changedTank);
eventAggregator.GetEvent<PartsDeletedEvent>().Publish(args);
在接收视图模型中,您需要订阅事件,例如在构造函数中。
eventAggregator.GetEvent<LogicalDirectoriesChangedEvent>().Subscribe(OnTankChanged);
创建方法OnTankChanged
来处理收到的事件。
private void OnLogicalDirectoriesChanged(TankChangedEventArgs args)
{
// Do something with the event arguments
}
您可以详细了解here。有关Caliburn Micro的示例,请参考this site。尽管这些机制内置于相应的框架中,但是您也可以在项目中单独使用它们,而无需迁移整个应用程序。但是,还有其他实现,但是这些框架是一个很好的起点,因为它们具有关于该主题的全面文档。