以下是模型:
public class Customer
{
string Name;
public ObservableCollection<Order> orders;
}
public class Order
{
int Id;
public ObservableCollection<RequestStorage> Requests;
}
public class RequestStorage
{
string Text;
public ObservableCollection<Response> Responses;
}
public class Response
{
string Text;
}
CustomersView.xaml 绑定到 CustomersViewModel ,其属性为ObservableCollection<*Customer*> Customers;
CustomersViewModel
<!-- language: c# -->
public class CustomersViewModel
{
public CustomersViewModel()
{
//Load customers from database to Customers
}
public ObservableCollection<Customer> Customers { get; set; }
}
CustomersView.xaml
窗口的DataContext
设置为CustomersViewModel
<DataGrid ItemsSource="{Binding Path=Customers}">
...
<DataGridTextColumn Header="Customer name" Binding="{Binding Path=Name}" />
...
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid ItemsSource="{Binding Path=Orders}">
...
<DataGridTextColumn Binding="{Path=Id}" />
<DataGridTemplateColumn>
<ItemsControl Binding="{Path=Requests}" />
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<ItemsControl DataContext="{Binding Requests}" Binding="{Path=Responses}" />
</DataGridTemplateColumn>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
问:当响应集合发生更改时(如添加了新响应),如何通知 CustomersViewModel ,以便 CustomersView.xaml 更新它是指定客户的UI吗?
答案 0 :(得分:0)
我现在实现的解决方案是一个包含CustomerRegister
的类List<Customer>
,并提供了获取/添加/编辑/保存a.s.o Customer
对象的方法。 CustomersViewModel
cantains CustomersRegister
。
此外,CustomerRegister
会在上升的事件处理程序发生任何更改时通知CustomersViewModel
。
最后,“模型”中的每个object
都会在其属性发生变化时通知CustomerRegister
。
这似乎很复杂,所以我会欣赏任何其他选择。
答案 1 :(得分:0)
好的,这是我用来收听子集合变化的类。也许你可以使用它。
public abstract class ChildListenerBase
{
public void RegisterChildCollection<T>(ObservableCollection<T> collection)
where T : INotifyPropertyChanged
{
// register to collection changed event
collection.CollectionChanged += OnCollectionChangedInternal;
// register to items
foreach (T item in collection)
item.PropertyChanged += OnItemPropertyChanged;
}
public void UnregisterChildCollection<T>(ObservableCollection<T> collection)
where T : INotifyPropertyChanged
{
// unregister to collection changed event
collection.CollectionChanged -= OnCollectionChangedInternal;
// unregister to item
foreach (T item in collection)
item.PropertyChanged -= OnItemPropertyChanged;
}
private void OnCollectionChangedInternal(object sender, NotifyCollectionChangedEventArgs e)
{
// probably you have to add some more cases
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
foreach (object item in e.NewItems)
((INotifyPropertyChanged) item).PropertyChanged += OnItemPropertyChanged;
break;
case NotifyCollectionChangedAction.Remove:
foreach (object item in e.OldItems)
((INotifyPropertyChanged) item).PropertyChanged -= OnItemPropertyChanged;
break;
}
OnCollectionChanged(sender, e);
}
protected virtual void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// override method in derived class to handle some additional stuff
}
// implement the reaction on item changes here
protected abstract void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e);
}