委派事件的模式



我将MVVM用于桌面应用程序。我有一个名为 Calculator 的模型,它在自己的线程中进行非常昂贵的计算。MainViewModel引用Calculator并使用计算结果。视图获取结果并显示它们。

问题是,Calculator使用事件返回计算结果。而且我不想将视图绑定到Calculator的事件,因为使用的Calculator可以在运行时更改。作为解决方案,我已经两次使用了同一个事件,我不喜欢,有人有更好的方法。

型:

public class Calculator
{
    public event CalculatedHandler Calculated;
    public delegate void CalculatedHandler(object sender, IEnumerable<string> values);
    protected void OnCalculated(IEnumerable<string> values)
    {
        Calculated?.Invoke(this, values);
    }
    public void Run()
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler(Calculate);
    }
    private void Calculate(object sender, DoWorkEventArgs e)
    {
        List<string> values = new List<string>();
        for (int i = 0; i < 10000; i++)
        {
            // Do expensive stuff
            values.Add(i + "");
            OnCalculated(values);
        }
    }
}

视图模型:

public class CalculatorViewModel
{
    private Calculator calculator;
    public event CalculatedHandler Calculated;
    public delegate void CalculatedHandler(object sender, IEnumerable<string> values);
    protected void OnCalculated(IEnumerable<string> values)
    {
        Calculated?.Invoke(this, values);
    }
    public CalculatorViewModel()
    {
        calculator = new Calculator();
        calculator.Calculated += Calculator_Calculated;
    }
    private void Calculator_Calculated(object sender, IEnumerable<string> values)
    {
        OnCalculated(values);
    }
}

查看 XAML:

<Window.DataContext>
    <viewmodels:CalculatorViewModel />
</Window.DataContext>

查看代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContextChanged += MainWindow_DataContextChanged;
    }
    private void MainWindow_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        CalculatorViewModel viewModel = e.NewValue as CalculatorViewModel;
        viewModel.Calculated += ViewModel_Calculated;
    }
    private void ViewModel_Calculated(object sender, IEnumerable<string> values)
    {
        // Draw values on the canvas
    }
}

在视图模型中实现 INotifyPropertyChanged,这是在数据更改时更新视图的常用方法。它可以很好地与绑定一起使用(我认为可以使用带有CanvasItemsControl作为其面板来显示计算结果,而无需代码隐藏(。

public class CalculatorViewModel: INotifyPropertyChanged
{
    private Calculator calculator;
    public event PropertyChangedEventHandler PropertyChanged;
    public IEnumerable<string> CalcValues { get; set; }
    public CalculatorViewModel()
    {
        calculator = new Calculator();
        calculator.Calculated += Calculator_Calculated;
    }
    private void Calculator_Calculated(object sender, IEnumerable<string> values)
    {
        CalcValues = values;
        PropertyChanged?.(this, new PropertyChangedEventArgs("CalcValues"));
    }
}

最新更新