Search code examples
c#wpfxamlmvvmcatel

Best practice is to use a model or a simple property?


I'm refactoring a piece of code I've written some times ago. I wrote a custom usercontrol that allows a user to select a counterpart.

The viewmodel has 2 properties defined as

#region Properties
[ViewToViewModel(MappingType = ViewToViewModelMappingType.TwoWayViewWins)]
public bool AllowNull
{
    get { return (bool)GetValue(AllowNullProperty); }
    set { SetValue(AllowNullProperty, value); }
}
public static readonly DependencyProperty AllowNullProperty = DependencyProperty.Register("AllowNull", typeof(bool),
    typeof(CounterpartChooserControl), new PropertyMetadata(default(bool)));


/// <summary>
/// This Dependency property is used upon KeyDown to propagate the click to the target usercontrol
/// </summary>
public ICommandSource DestinationControl
{
    get { return (ICommandSource)GetValue(DestinationControlProperty); }
    set { SetValue(DestinationControlProperty, value); }
}

public static readonly DependencyProperty DestinationControlProperty = DependencyProperty.Register("DestinationControl", typeof(ICommandSource), typeof(CounterpartChooserControl),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None));
#endregion

and in the view I need to use it I do something as

  <views4:CounterpartChooserControl Grid.Row="9" Grid.Column="1" Margin="5,2,5,2" DataContext="{Binding CounterPartModel}" >
        </views4:CounterpartChooserControl>

This means that I've in the viewmodel a property defined as

[ViewModelToModel("Model")]
public CounterPartModel CounterPartModel
{
    get { return GetValue<CounterPartModel>(CounterPartModelProperty); }
    set { SetValue(CounterPartModelProperty, value); }
}

public static readonly PropertyData CounterPartModelProperty = RegisterProperty("CounterPartModel", typeof(CounterPartModel), null);

The problem I'm facing right now is that when the SelectedItem (which is defined in the CounterpartChooserViewModel) is changed this information is not directly propagated to the main viewmodel (and that's reasonable since it's inside a viewmodel and so the nested property is not notified in the main viewmodel).

Is this ok or should I have a SelectedCounterpart in the main viwemodel, bind it via XAML as

and have the datacontext resolved somehow by the view itself?


Solution

  • Since not all context is available, I am going to assume a few things here and there.

    It's ok because you are actually handling a model inside the sub vm. The sub vm is only aware of the model it has (CounterPartModel). If it is the same reference, then the changes you make to the model inside the sub vm should directly be visible in the main vm.

    Otherwise you have to set up some form of communication (messaging, services, interested in, etc) to notify other vms of changes.