PropertyChangedCallback 只触发了一次?
在自定义的用户控件中,添加一个依赖属性,如下:
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(Dictionary<string, object>), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(MultiSelectComboBox.OnItemsSourceChanged))); public Dictionary<string, object> ItemsSource { get { return (Dictionary<string, object>)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { MultiSelectComboBox control = (MultiSelectComboBox)d; control.DisplayInControl(); }
使用MVVM模式,在Views中添加这个控件;在ViewModel中给ItemsSource设定绑定值,如下:
views:
<control:MultiSelectComboBox x:Name="mcWind" Visibility="{Binding ShowWind, Converter={StaticResource BooleanToVisibilityConverter}}" ItemsSource="{Binding ItemsWind,Mode=TwoWay}" SelectedItems="{Binding SelectedItemsWindt, Mode=TwoWay}" />
ViewModel:
public void InitWind() { if (ItemsWind == null ) { ItemsWind = new Dictionary<string, object>(); } ItemsWind.Clear(); var lstStation = GetSelectedStationIds(); var lstModel = GetSelectedModelIds(); foreach (var kv in DataCache.Instance.Winds) { //WindTurbine w = kv.Value as WindTurbine; if (lstStation.Contains(kv.WindPowerStationId) && lstModel.Contains(kv.ModelId)) { ItemsWind.Add(kv.Name, kv); } } }
这时问题来了:在ViewModel中多次执行InitWind, 只有第一次PropertyChangedCallback 成功了,后续再修改ItemsWind,控件中的ItemSource更新了,但是PropertyChangedCallback 却不触发了。简单的讲,就是依赖属性的绑定成功了,但属性改变的回调函数却不触发~
在stackoverflow中有人似乎遇到了同样的情况,但回复的大牛们似乎都搞错了状况:
http://stackoverflow.com/questions/10139475/dependencyproperties-propertychangedcallback-only-called-once
http://stackoverflow.com/questions/5795770/wpf-propertychangedcallback-triggered-only-once
很多人说绑定被破坏、死循环云云~,就是没有合适的解决方法
最终我的处理方案,其实很简单:在ViewModel中给一个新的地址(引用),如下:
public void InitWind() { Dictionary<string, object> dictWind = new Dictionary<string, object>(); var lstStation = GetSelectedStationIds(); var lstModel = GetSelectedModelIds(); foreach (var kv in DataCache.Instance.Winds) { if (lstStation.Contains(kv.WindPowerStationId) && lstModel.Contains(kv.ModelId)) { dictWind.Add(kv.Name, kv); } } ItemsWind = dictWind; }
浪费了大半天时间调试,作此笔记备忘~