views:

68

answers:

2

I thought what I was doing was right out of the Josh Smith MVVM handbook, but I seem to be having a lot of problems with value converters firing when no data in the view-model has changed.

So, I have a ContentControl defined in XAML like this:

<ContentControl Grid.Row="0" Content="{Binding CurrentViewModel}" />

The Window containing this ContentControl references a resource dictionary that looks something like this:

<ResourceDictionary ...>
    <DataTemplate DataType="{x:Type lib_vm:SetupPanelViewModel}">
        <lib_v:SetupPanel />
    </DataTemplate>
    <DataTemplate DataType="{x:Type lib_vm:InstructionsPanelViewModel}">
        <lib_v:InstructionsPanel />
    </DataTemplate>
</ResourceDictionary>

So, basically, the two data templates specify which view to show with which view-model.

This switches the views as expected whenever the CurrentViewModel property on my window's view-model changes, but it also seems to cause value converters on the views to fire even when no data has changed. It's a particular problem with IMultiValueConverter classes, because the values in the value array get set to DependencyProperty.UnsetValue, which causes exceptions unless I specifically check for that. But I'm getting other weird side effects too.

This has me wondering if I shouldn't just do everything manually, like this:

  1. Instantiate each view.
  2. Set the DataContext of each view to the appropriate view-model.
  3. Give the ContentControl a name and make it public.
  4. Handle the PropertyChanged event for the window.
  5. In the event handler, manually set the Content property of the ContentControl to the appropriate view, based the CurrentViewModel (using if statements).

This seems to work, but it also seems very inelegant. I'm hoping there's a better way.

Could you please advise me the best way to handle view switching so that value converters don't fire unnecessarily?

+1  A: 

You should look at PRISM or any other composite UI framework. Prism will give you a great mechanism for this type of thing.

Chris Nicol
+1  A: 

I solved this by getting rid of all IValueConverter and IMultiValueConverter classes and just using the ViewModel to provide all data. It turns out, this requires less code and hassle, and doesn't sacrifice anything that I'm aware of.

DanM