I use MVVM for a desktop application. I have a model called Calculator
, which does very expensive calculations in a own thread. The MainViewModel
references the Calculator
and uses the calculated results. The view takes the results and displays them.
The problem is, that the
Calculator
returns the calculation results by using an event. And I don't want to bind the view to the event from theCalculator
because the usedCalculator
can change on runtime. As solution I have used the same event twice, which I don't like, has someone a better approach.
Model:
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);
}
}
}
ViewModel:
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);
}
}
View XAML:
<Window.DataContext>
<viewmodels:CalculatorViewModel />
</Window.DataContext>
View code behind:
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
}
}