绑定不能像MSDN中描述的那样工作

时间:2013-11-29 13:49:23

标签: c# wpf data-binding mvvm inotifypropertychanged

在正确实现INotifyPropertyChanged的WPF数据绑定中,应该强制执行GUI的渲染事件。不知怎的,我找到了一个没有的例子。我想将ObservableCollection<Point>绑定到Points的{​​{1}}属性。因此Polyline只接受Points我需要PointCollection。每当Bining工作正常时,Converter就会创建一个PointCollection的新实例。但是当我在转换器中创建一个私有字段(类型为IValueConverter)时,它存储数据并对其应用更改(例如添加或删除PointCollection)),那么Point不会呈现!

XAML:

Polyline

转换器:

<canvas>
 <Polyline Stroke="blue" Width="Auto" Height="Auto" Points="{Binding points, Converter=DataPointConverter}"></Polyline>
</canvas>

事实上,这些点已正确添加到class DataPointConverter : IValueConverter { private PointCollection privatePoints; public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { IEnumerable<Point> _enumerable = value as IEnumerable<Point>; if (_enumerable == null) { throw new InvalidOperationException("Source collection must be of type IEnumerable<Point>"); } if (privatePoints == null) { privatePoints = new PointCollection(_enumerable); INotifyCollectionChanged _notifyCollectionChanged = _enumerable as INotifyCollectionChanged; if (_notifyCollectionChanged != null) { _notifyCollectionChanged.CollectionChanged += this.Source_CollectionChanged; } } return privatePoints; //next line would work! but i don't want to copy the entire list every time //return new PointCollection(_enumerable); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: for (int i = 0; i < e.NewItems.Count; i++) { privatePoints.Insert(e.NewStartingIndex + i, (Point)e.NewItems[i]); } break; case NotifyCollectionChangedAction.Move: for (int i = 0; i < e.NewItems.Count; i++) { privatePoints.RemoveAt(e.OldStartingIndex); privatePoints.Insert(e.NewStartingIndex + i, (Point)e.NewItems[i]); } break; case NotifyCollectionChangedAction.Remove: for (int i = 0; i < e.OldItems.Count; i++) { privatePoints.RemoveAt(e.OldStartingIndex); } break; case NotifyCollectionChangedAction.Replace: for (int i = 0; i < e.NewItems.Count; i++) { privatePoints[e.NewStartingIndex + i] = (Point)e.NewItems[i]; } break; case NotifyCollectionChangedAction.Reset: privatePoints.Clear(); break; } } (我可以在强制渲染事件时看到它们,例如更改Polyline的{​​{1}}。但在我看来,绑定应该触发渲染。 (我甚至检查了Stroke

我做错了吗?或者这是.NET Framework的未记录的“功能”吗?

我的消息来源:基本上我实施了Tamir Khason在blog中所写的内容。 (他为donwnload提供的解决方案不起作用。他永远不会从字典中返回值,但始终是新创建的集合)

1 个答案:

答案 0 :(得分:0)

请你试试吗

<canvas>
 <Polyline Stroke="blue" Width="Auto" Height="Auto" Points="{Binding     points,Mode=TwoWay,updatesourcetrigger=propertychanged, Converter=DataPointConverter}">   </Polyline>
</canvas>