Reputation: 3661
Im currently trying to get my first WPF Usercontrol to work. It consists of some UI elements and a ViewModel, holding the data and doing the work. It has a List of items as input, and another List of items as output. I need a certain task in my ViewModel to be done, when the list bound to the input changes. But i can't find a way to run a method at change of this List.
I thought the best way is to have 2 DependencyProperties for the input and output list. If the output list changes, the bound objects should be informed as it is registered as DependencyProperty. And i wanted to use the DependencyPropertyChanged delegate to specify the method in my ViewModel to execute on Input change.
public List<AClass> Input
{
get { return (List<AClass>)GetValue(InputProperty); }
set { SetValue(InputProperty, value); }
}
public static readonly DependencyProperty InputProperty =
DependencyProperty.Register("Input", typeof(List<AClass>), typeof(MyUserControl), new UIPropertyMetadata(new List<AClass>(),CallBackDelegate));
I tried different approaches to set the delegate in the viewmodel constructor, but they all did not work. How can I specify a method within my viewmodel to execute on change of input List?
Upvotes: 0
Views: 687
Reputation: 10823
Instead of lists in a DependencyProperty, I would use ObservableCollections. That gives you "automatic" notifications, etc. Here is outta-my-head-probably-not-quite-complete pseudo code to get you started:
ViewModel
using System.Collections.ObjectModel;
namespace MyNamespace;
class MyViewModel
{
ObservableCollection<AClass> mInput = new ObservableCollection<AClass>();
ObservableCollection<AClass> mOutput = new ObservableCollection<AClass>();
public MyViewModel()
{
mInput.CollectionChanged +=
new NotifyCollectionChangedEventHandler(mInput_CollectionChanged);
}
void mInput_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
DoSomething();
}
public ObservableCollection<AClass> Input
{
get { return mInput; }
}
public ObservableCollection<AClass> Output
{
get { return mOutput; }
}
}
Somewhere in Control/View
<ItemsControl ItemsSource="{Binding Input}">
<!-- Rest of control design goes here -->
</ItemsControl>
<ItemsControl ItemsSource="{Binding Output}">
<!-- Rest of control design goes here -->
</ItemsControl>
Control/View Code-Behind
class MyViewOrControl
{
// ViewModel member
private readonly MyViewModel mViewModel = new MyViewModel();
// Constructor
public MyViewOrControl()
{
InitializeComponent();
this.DataContext = mViewModel;
}
// Property (if needed)
public ViewModel
{
get { return mViewModel; }
}
}
Upvotes: 1