委派活动的模式

时间:2017-02-13 08:56:14

标签: c# wpf events design-patterns mvvm

我将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
    }
}

1 个答案:

答案 0 :(得分:3)

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

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