在WPF中我试图尽可能地成为MVC / VM。我有一个用户控件(ReservationDataControl),它有一个带有上下文菜单和一些过滤器按钮的数据网格。用户可以从上下文菜单中添加,删除等,它们都在usercontrol中处理。此控件与另一个用户控件位于同一窗口,我收集有关已付人数和获得的数量的统计信息(PartyStatsControl)。
当用户编辑ReservationDataControl时,我需要PartyStatsControl进行更新(因此它们将有效)。什么是最好的MVC / VM方式?
我应该从ReservationDataControl举起一个事件吗?有没有办法绑定命令?控件在MVC / VM中通知其主机更改的可接受方式是什么。
顺便说一句:我使用MVC / VM是因为我从来没有设法在我的头脑中得到两者之间的差异,而不是与我正在使用的方法论争论我只是警察不知道马上蝙蝠答案 0 :(得分:0)
与大多数工程设计一样,没有正确和错误答案,这一切都取决于方案。在后面的代码中处理事件并适当地调用视图模型是完全正确的(假设您在实例化时已将视图模型的引用传递到视图中)。
然而,您可以绑定命令,我更喜欢这种方法,因为它更松散耦合。此命令中的操作将设置模型(在这种情况下,在创建 ReservationDataViewModel 时传入的 _statistics 实例)。
ReservationDataControl查看:
<Button Command={Binding ClickCommand}/>
ReservationDataControl视图模型(数据上下文):
private readonly Statistics _statistics;
public ICommand ClickCommand { get; set; }
private ReservationDataViewModel(Statistics statistics)
{
_statistics = statistics;
InitialiseCommands();
}
private void InitialiseCommands()
{
ClickCommand = new RoutedUICommand("ClickCommand", "ClickCommand", typeof(ViewModel));
CommandBinding clickCommandBinding = new CommandBinding(ClickCommand, ExecuteClickCommand, ClickCommandCanExecute);
CommandManager.RegisterClassCommandBinding(typeof(ViewModel), clickCommandBinding);
}
private void ExecuteClickCommand(object sender, ExecutedRoutedEventArgs args)
{
// perform click logic here...
// e.g. say there is a property on your statistics called 'ReservationCount'
// the command adds a reservation (increments the count)
_statistics.ReservationCount += 1;
}
private void ClickCommandCanExecute(object sender, CanExecuteRoutedEventArgs args)
{
args.CanExecute = true; // put your can execute logic here...
}
现在,如果您的模型(即统计类)设置正确,它应该能够告诉任何关心它已经更改的代码。
即
public class Statistics
{
public event EventHandler ReservationCountChanged;
private int _reservationCount;
// think about how you may restrict set access for this model
public int ReservationCount
{
get { return _reservationCount; }
protected set
{
if (_reservationCount != value)
{
_reservationCount = value;
if (ReservationCountChanged != null)
ReservationCountChanged(this, new EventArgs());
}
}
}
public Statistics() { }
}
现在, PartyStatsViewModel 可以从 ReservationDataViewModel 中获取此更改,并使用标准WPF绑定实现更新其视图。
PartyStatsControl查看模型:
private readonly Statistics _statistics;
public int ReservationCount
{
get { return _statistics.ReservationCount; }
set
{
_statistics.ReservationCount = value;
OnPropertyChanged("ReservationCount");
}
}
public PartyStatsControlViewModel(Statistics statistics)
{
_statistics = statistics;
_statistics.ReservationCountChanged += OnReservationCountChanged;
}
private void OnReservationCountChanged(object sender, RoutedEventArgs args)
{
// todo: force this onto the UI thread or exceptions will occur
this.ReservationCount = ((Statistics)sender).ReservationCount;
}