2015-12-02 77 views
1

我有簡單UserControl其中定義的屬性ItemsSource用戶控件自定義的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(); 
     } 

我想使這個屬性更新動態,但我不知道爲什麼OnItemsSourceChanged不會每次當發射時間有些東西與ItemsSource發生。所以我很不高興。 我試過Custom ItemsSource property for a UserControl但這並不能幫助或者我寫壞newValueINotifyCollectionChanged_CollectionChanged功能


我的控制是從這個帖子CodeProject


我的代碼: 用戶控件XAML - http://pastie.org/10606317

UserControl CodeBehind - 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不是空的(從開始它)。所以如果我正確理解這種行爲,現在問題就在於重繪控件內容。

+0

在你的類的靜態構造函數中定義你的DP。 – AnjumSKhan

+0

public static readonly DependencyProperty ItemsSourceProperty; DependencyProperty.Register(「ItemsSource」,typeof(Dictionary ),typeof(UserControl1),new FrameworkPropertyMetadata(null, new PropertyChangedCallback(UserControl1.OnItemsSourceChanged)));靜態YourClassName(){ItemsSourceProperty = ; } – AnjumSKhan

+0

@AnjumSKhan - 我試過後,我得到了異常 - '其他信息:'ItemsSource'屬性已經被'UserControl1'註冊了。' – demo

回答

0

我看到的問題是,你正在爲你的自定義UserControlComboBox控制建設新ItemsSource,和你期望的是MultiSelectCombo.ItemsSource能夠輕鬆的與您的UserControl1.ItemsSource同步。這僅僅是在綁定Dictionary時不會發生,即使綁定ObservableCollection也不會發生 - 除非您明確處理它。

爲了實現您所追求的目標,首先您需要將自定義控件的ItemsSource作爲一種類型,它會將收集更改通知給我們,例如ObservableCollection(我將用於此示例,已經在上面的鏈接中完成)。然後,您需要更新您控制範圍內的ComboBoxItemsSource,以使其保持同步。

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(); 
} 

現在,這麼說,上述解決方案是一個更通用的情況下,用戶可能需要將其傳遞到你的MultiSelectCombo.ItemsSource之前做給您的自定義控制ItemsSource東西。但是,在您目前的情況下,您只需構建一個Node的集合,以與給定的Node集合完全匹配。如果有保證是這種情況,您的解決方案可能是非常非常簡單:

private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var control = (MultiSelectComboBox)d; 
    control.MultiSelectCombo.ItemsSource = (IEnumerable)e.NewValue; 
} 

只是讓包裹ComboBox使用提供給您的自定義控制ItemsSource

+0

'((ObservableCollection這個應該是'e.NewValue'? – demo

+0

我試過「更簡單」的示例,但這並不能解決我的問題。不知道爲什麼... – demo

+0

@demo是的,對不起,這是從複製粘貼錯誤。你是對的,應該是'e.NewValue'。兩種解決方案是否解決您的問題似乎你應該能夠將'UserControl'的'ItemsSource'傳遞給'ComboBox'並且仍然有效。您確定這些項目已添加到正確的源實例中? –

1

如果您有一本字典作爲您的數據類型,並且您從字典中添加或刪除一個值,那麼您的屬性實際上並沒有改變。如果您已將該屬性設置爲引用其他字典,則該事件僅會觸發。

如果您需要wpf自動檢測是否添加或從字典中刪除項目,則應使用ObservableCollection。

+0

我試過'ObservableCollection',但仍然是我的控件的'ItemsSource'是一樣的 – demo

+0

只是爲了澄清,你是否試圖在添加或刪除項目時更新控件? – user3308241

+0

另外,是否可以在問題的底部發布用戶控件的xaml?也許這會澄清你需要做什麼來解決這個問題。 – user3308241

1
  1. 將字典替換爲ObservableCollection,當添加,更新,刪除項目時,字典不會觸發propertyChanged事件。
  2. 編寫您自己的字典以手動觸發propertychanged事件。
+0

我試過ObservableCollection,但我的控件的ItemsSource仍然是一樣的 – demo