在自定義的用戶控件中,添加一個依賴屬性,如下:
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; }
浪費了大半天時間調試,作此筆記備忘~
