我的usercontrol应该如何通知我的视图

本文关键字:我的 通知 视图 何通知 usercontrol | 更新日期: 2023-09-27 18:08:17

在WPF我试图成为MVC/VM尽可能。我有一个用户控件(reservationdat控件),它有一个带有上下文菜单和一些过滤按钮的数据网格。用户可以从上下文菜单中添加、删除等,这些都在usercontrol中处理。这个控件与另一个用户控件位于同一窗口上,我在那里收集关于有多少人支付和赚了多少钱的统计数据(PartyStatsControl)。

当用户编辑reservationdat控件时,我需要更新PartyStatsControl(因此它们将有效)。最好的MVC/VM方式是什么?

我应该从reservationdatacro中引发一个事件吗?是否有一种绑定命令的方法?在MVC/VM中,控件通知主机更改的可接受方式是什么?

BTW:我使用MVC/VM,因为我从来没有设法弄清楚两者之间的区别在我的头脑中,而不是争论我使用的方法,我只是承认不知道马上。

我的usercontrol应该如何通知我的视图

与大多数工程一样,没有正确的错误的答案,这完全取决于场景。在后台代码中处理事件并适当地调用视图模型是完全可以的(前提是在实例化时将视图模型的引用传递给视图)。

但是,您可以绑定到命令,我更喜欢这种方法,因为它更松散耦合。该命令中的操作将设置模型(在本例中,在创建ReservationDataViewModel时传入的_statistics实例)。

ReservationDataControl视图:

<Button Command={Binding ClickCommand}/>

reservationdatactrol View Model (Data Context):

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...
}

现在,如果你的模型(即Statistics类)设置正确,它应该有一种方法告诉任何关心它已经更改的代码。

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;
}