2010-03-17 56 views
3

我試着的名單在WPF上下文菜單那是一個依賴屬性顯示出來,使內容。勢必列表WPF上下文菜單<>依賴屬性

我有以下依賴屬性的類,Foo的(數據保持類)的列表:

public List<Foo> FooList 
    { 
     get { return (List<Foo>)GetValue(FooListProperty); } 
     set { SetValue(FooListProperty, value); } 
    } 
    public static DependencyProperty FooListProperty = 
     DependencyProperty.Register("FooList", typeof(List<Foo>), 
      typeof(FooButton)); 

在XAML我設置了以下靜態資源,我認爲它的,因爲上下文菜單心不是需要可視化樹的一部分:以上的ResourceDictionary的

<UserControl.Resources> 
    <ResourceDictionary>    
     <CollectionViewSource 
      x:Key="FooListSource" 
      Source="{Binding FooList}"/> 

     <!-- ... --> 

    </ResourceDictionary> 
</UserControl.Resources> 

也有一部分是它使項目在實際的上下文菜單中出現需要CompositeCollection。如果UserControl CanStop屬性爲true,我們還會顯示一個分隔符和一個停止命令。儘管MenuItem本身顯示,但這些綁定也會失敗。所以如果我能弄清楚爲什麼這些失敗,那麼列表可能會更容易。

<CompositeCollection x:Key="FooListItems"> 
    <CollectionContainer 
     Collection="{Binding Source={StaticResource FooListSource}}"/> 
    <Separator 
     Visibility="{Binding CanStop, 
      Converter={StaticResource VisibleIfTrue}}" /> 
    <MenuItem 
     Command="{x:Static Buttons:FooButton.Stop}" 
     Header="Stop" 
     Visibility="{Binding CanStop, 
      Converter={StaticResource VisibleIfTrue}}"/> 
</CompositeCollection> 

最後上下文菜單本身,也是在ResourceDictionary中:

<ContextMenu 
    x:Key="FooButtonMenu" 
    ItemsSource="{Binding Source={StaticResource FooListItems}}" 
    ItemTemplate="{StaticResource FooListTemplate}" 
    <ContextMenu.CommandBindings> 
     <CommandBinding 
       Command="{x:Static Buttons:FooButton.Stop}" 
       Executed="Stop_Executed" /> 
    </ContextMenu.CommandBindings> 
</ContextMenu> 

我覺得林發帖的方式很多代碼,但林不知道我可以做這一塊的任何簡單。只有分隔符和硬編碼的菜單項出現。所以有些東西必須與綁定混淆。綁定通常並不那麼困難,但現在當我想綁定一些不屬於同一棵樹的東西時,我感覺有點失落。

歡迎任何建議。 :)

+0

你如何使用FooList的DependencyProperty?特別是,您是否將完全填充的列表分配給屬性,或者您是否將空列表分配給屬性,然後再填充列表?該會的DependencyProperty傳播分配到一個完全新的列表,但如果要監視列表中的變化,你需要使用的ObservableCollection或其他一些實現INotifyCollectionChanged的。 – 2010-03-17 15:32:18

+0

調用一個函數來觸發數據從舊系統中讀取,我循環執行'FooList'的數據。加入(myNewFoo);'。你是說我應該簡單地將'List <>'換成'ObservableCollection <>'? – Mizipzor 2010-03-17 15:38:04

+0

呃..一切似乎都對我好!你能否把你的演示項目上傳到某個地方?可能是你缺少一個DataContext? – mg007 2010-03-17 18:45:36

回答

1

當你懷疑,你的問題似乎確實通過使用List<Foo>代替ObservableCollection<Foo>引起的。由於List<Foo>沒有通知對房地產的變化,讓WPF識別您添加或刪除項目的唯一方法是臨時設置FooList屬性到別的東西,然後將其設置回。

沒有必要切換到CLR屬性。只需將List<Foo>更改爲ObservableCollection<Foo>即可。

您的CompositeCollection中的綁定不起作用的原因是CompositeCollection不是DependencyObject,因此它不能繼承DataContext

+0

是否有替代CompositeCollection我可以使用它是一個DependencyObject?雖然只有在顯示上下文菜單後才更新這些項目,而我曾經這麼做了代碼隱藏中的簡單方法,但我現在想嘗試使用它。 – Mizipzor 2010-03-18 08:05:43

+0

簡單地交換List for ObservableCollection似乎可以使它工作。 – Mizipzor 2010-03-18 08:12:15

0

我不明白爲什麼你做FooList一個依賴屬性。你沒有把它作爲綁定的目標,這是創建依賴項屬性的最常見原因。您尚未實現回調,因此無法更改通知(創建依賴項屬性的第二個常見原因)。你沒有使用它來實現價值繼承。那麼爲什麼呢?

在我看來,你真正想要的是FooList是類型ObservableCollection<Foo>(或實現INotifyCollectionChanged的任何類)的正常CLR屬性。這將完成您需要的所有更改通知 - 至少,您需要獲得迄今爲止發佈的代碼。

+0

這聽起來像是一條紅鯡魚給我。我們可以整天辯論是否使FooList成爲DependencyProperty或CLR屬性是合適的。最底層的是,DependencyProperty可以完成CLR屬性可以做的所有事情等等。儘管在某些情況下可能會被認爲是一個糟糕的選擇(我不確定這是否是其中之一),但它與mizipzor所面臨的問題無關。 – 2010-03-17 22:00:34

+0

你是對的,無論它是否是依賴屬性都沒關係。實際上重要的是它的類型是實現'INotifyCollectionChanged'的集合。 – 2010-03-18 00:35:19