[英]Combobox SelectedItem doesn't update when ItemsSource changes MVVM
[英]UserControl with custom ItemsSource doesn't detect changes
我有簡單的UserControl
在哪里定義屬性ItemsSource
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(Dictionary<string, object>), typeof(UserControl1), new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(UserControl1.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)
{
UserControl1 control = (UserControl1)d;
control.DisplayInControl();
}
我想使此屬性動態更新,但我想知道為什么在ItemsSource發生某些情況時不會每次觸發OnItemsSourceChanged
。 所以我很傷心。 我已經嘗試了UserControl的Custom ItemsSource屬性,但這無濟於事,或者我編寫了錯誤的newValueINotifyCollectionChanged_CollectionChanged
函數
我的控制權來自此Post CodeProject
我的代碼:UserControl XAML- http ://pastie.org/10606317
用戶控件代碼隱藏- http://pastie.org/10606322
控制用法-
<controls:MultiSelectComboBox SelectedItems="{Binding SelectedCategories, Mode=TwoWay}" Grid.Column="0" Grid.Row="0" x:Name="CategoriesFilter" DefaultText="Category" ItemsSource="{Binding Categories }" Style="{StaticResource FiltersDropDowns}"/>
更新:我已邁出了很小的一步來解決問題。 我有下一種風格:
<Style.Triggers>
<DataTrigger Binding="{Binding ItemsSource, RelativeSource={RelativeSource Self}}" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
<DataTrigger Binding="{Binding ItemsSource.Count, RelativeSource={RelativeSource Self}}" Value="0">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
我將其應用於控件(如果沒有itemSource,則禁用控件)。 在單擊時更新控件源時,我看到控件已啟用,因此ItemsSource不會為空(從開始就為空)。 因此,如果我正確理解此行為,那么現在的問題只是在重繪控件內容中。
如果您有一個字典作為您的數據類型,並且您在字典中添加或刪除了一個值,那么您的屬性實際上並沒有發生變化。 僅當您實際上已將此屬性設置為引用其他字典時,才會觸發此事件。
如果需要wpf自動檢測是否在字典中添加或刪除了一項,則應使用ObservableCollection。
我看到問題在於您正在為自定義UserControl
的ComboBox
控件構建新的ItemsSource
,並且希望MultiSelectCombo.ItemsSource
與UserControl1.ItemsSource
保持同步。 如果僅綁定Dictionary
,則不會發生這種情況;即使綁定ObservableCollection
,也不會發生這種情況-除非您明確處理它。
為了完成您要做的事情,首先,您需要將自定義控件的ItemsSource
為確實會通知我們集合更改的類型,例如ObservableCollection
(在本示例中,我將使用它,就像您在上面的鏈接)。 然后,您需要在控件中更新ComboBox
的ItemsSource
,以使其保持同步。
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (MultiSelectComboBox)d;
// Since we have to listen for changes to keep items synced, first check if there is an active listener to clean up.
if (e.OldValue != null)
{
((ObservableCollection<Node>)e.OldValue).CollectionChanged -= OnItemsSource_CollectionChanged;
}
// Now initialize with our new source.
if (e.NewValue != null)
{
((ObservableCollection<Node>)e.NewValue).CollectionChanged += OnItemsSource_CollectionChanged;
control.DisplayInControl();
}
}
private void OnItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
DisplayInControl();
}
就是說,上面的解決方案是針對更通用的情況的,在這種情況下,您可能需要對傳遞給自定義控件的ItemsSource
進行處理,然后再將其傳遞到MultiSelectCombo.ItemsSource
。 在當前的情況下,然而,你只是建立集合Node
,以給定集合完全匹配Node
。 如果可以保證的話,您的解決方案可能會簡單得多:
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (MultiSelectComboBox)d;
control.MultiSelectCombo.ItemsSource = (IEnumerable)e.NewValue;
}
只需讓包裝ComboBox
使用提供給自定義控件的ItemsSource
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.