我有以下viewmodel,我想绑定到视图:
public class EntityManagerModel
{
public readonly ObservableCollection<EntityViewModel> m_Entities =
new ObservableCollection<EntityViewModel>();
}
//
// implements INotifyPropertyChanged
public class EntityManagerViewModel: BaseViewModel
{
private EntityManagerModel m_Model = new EntityManagerModel();
public ObservableCollection<EntityViewModel> Entities
{
get { return m_Model.m_Entities; }
}
}
然而,我实际想要绑定到我的视图的是EntityViewModel
中包含的数据,其定义如下:
public class EntityModel
{
public readonly PointCollection m_TrailPoints = new PointCollection();
}
//
// implements INotifyPropertyChanged
public class EntityViewModel: BaseViewModel
{
private EntityModel m_Model = new EntityModel;
public PointCollection TrailPoints
{
get { return m_Model.m_TrailPoints; }
}
}
所以,每当我添加这样一个点时,我都希望我的观点更新:
// In some routine inside EntityManageViewModel I have this code
// this should trigger collectionChanged event:
Entities[index].TrailPoints.Add( new Point(x, y));
我的观点的XAML代码是:
<!-- EntityManagerView -->
<Grid>
<!--Trail line-->
<ItemsControl ItemsSource="{Binding Entities}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type vm:EntityViewModel}">
<Polyline Stroke="Red" StrokeThickness="1">
<Polyline.Style>
<Style TargetType="{x:Type Polyline}">
<Setter Property="Points">
<Setter.Value>
<MultiBinding Converter="{StaticResource pointMultiConverter}">
<Binding Path="ActualWidth" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Canvas}}"/>
<Binding Path="ActualHeight" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Canvas}}"/>
<Binding Path="TrailPoints"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Polyline.Style>
</Polyline>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
这仅在我调整应用程序窗口大小时显示/更新行。当然,我在搜索时找到了像this这样的解决方案。但是,子类ObservableCollection
在我的代码中引入了其他问题。那么,我的问题是这样做的最佳/替代方法是什么?
答案 0 :(得分:1)
最简单的解决方案&#34;模拟&#34;可观察集合是将以下行添加到EntityViewModel
:
public EntityViewModel()
{
TrailPoints.Changed += (sender, args) => RaisePropertyChanged("TrailPoints");
}
每当更改TrailPoints
集合时(例如,添加Point
时),都会引发其Changed
事件。我们的想法是订阅此事件并引发PropertyChanged
事件以通知View有关集合已更改的信息!
答案 1 :(得分:0)
基本上,您需要挂钩父视图模型上更改的集合。
this.Entities.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(EntitiesItems_CollectionChanged);
void EntitiesItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e){
if (e.NewItems != null) {
((EntityModel)e.NewItems[0]).PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(TrailPoints_PropertyChanged);
}
OnPropertyChanged("Entities");
}
void TrailPoints_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) {
if (e.PropertyName == "TrailPoints") {
OnPropertyChanged("Entities");
}
}
当前viewModel上的INotifyPropertyChanged仅深入一级。通过挂钩集合中更改的每个属性,您可以确定如何处理集合的特定更改(添加,删除等)