Reputation: 984
Given I have this UserControl:
public class MyStringUserControl : UserControl
{
public string MyString
{
get { return (string)GetValue(MyStringProperty); }
set { SetValue(MyStringProperty, value); }
}
public static readonly DependencyProperty MyStringProperty =
DependencyProperty.Register("MyString", typeof(string), typeof(MyStringUserControl),
new FrameworkPropertyMetadata(null));
}
And this ViewModel:
public class MyStringViewModel
{
public string MyString { get; set; }
}
Now I use the MyStringUserControl in another View like this:
<controls:MyStringUserControl MyString="{Binding SomeStringProperty} />
I'am looking for an elegant way to bind this string back to the MyStringViewModel.
I also don't feel comfortable with the fact that I have to duplicate every property in the UserControl code behind and ViewModel. Is there a better way to do this?
The reason I want to do this is because of unit testing (creating a UserControl takes very long even without InitializeComponent)
Upvotes: 0
Views: 1738
Reputation: 69959
There is absolutely no point in duplicating your properties. Using MVVM does not mean that you need to have a view model for every UserControl
. When I use a UserControl
as a part of a view, I rarely use a separate view model for it. Sometimes, I'll just use the DependencyProperty
s in the UserControl
code behind, while other times I'll just data bind to the parent view model directly. It all depends on what you want to do with the data.
Upvotes: 2
Reputation: 4950
If I was intent on doing this, I would use DependencyProperty's PropertyChanged event handler to set my ViewModel's property, and my ViewModel's PropertyChanged event handler to set my DependencyProperty. Having said that I've never had a reason to go down this particular road.
private SomeViewModel _viewModel;
public static readonly DependencyProperty MyStringProperty = DependencyProperty.Register("MyString", typeof(string), typeof(MyStringUserControl), new PropertyMetadata(OnMyStringChanged));
public MyStringUserControl()
{
InitializeComponent();
_viewModel = new SomeViewModel();
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
this.DataContext = _viewModel;
}
private static void OnMyStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyStringUserControl)d).OnMyStringChanged(e.NewValue);
}
private void OnMyStringChanged(string newValue)
{
_viewModel.SomeProperty = newValue;
}
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "SomeProperty":
SetValue(MyStringProperty, _viewModel.SomeProperty);
break;
default:
break;
}
}
Upvotes: 0