2010-12-14 10 views
0

タブのコンテキストメニュー(チェックボックス付き)を観察可能なコレクションにバインドしようとしています。初めてmenuitemをチェックするかアンチェクすると、その状態はobesarvableコレクションのbool変数に関連付けられた に反映されます。しかしその後、それは反映されません。 XAMLでの結合は次のようになります。WPFコンテキストメニューのデータバインド

データ・テンプレートが

 <DataTemplate x:Key="SelectIndexFieldMenu"> 
      <MenuItem Header="{Binding Path=IndexFieldName}" 
         IsCheckable="True" 
         IsChecked="{Binding Path=isIndexFieldSelected,Mode=TwoWay}" 
         IsEnabled="{Binding Path=isCheckBoxEnabled}" /> 
     </DataTemplate> 

(:(私は、コードスニペットを追加することはできませんよ、私は「<」を削除) 監視可能なコレクションのためのクラスです

 <TabItem.ContextMenu> 
      <ContextMenu Name="menu" 
         ItemsSource="{Binding Path=FieldNameCollection,Mode=TwoWay}" 
         ItemTemplate="{StaticResource SelectIndexFieldMenu}"></ContextMenu> 
     </TabItem.ContextMenu> 
NotifierBaseから派生したものです ContextMenuClosingでコンテキストメニューのitemsourceをview.xaml.csでチェックすると、状態が正しく反映されていることに気がつきました。

+0

あなたのクラスに 'INotifyPropertyChanged'インターフェースを実装していますか? – decyclone

+0

はい、私はINotifyProperyChangedを実装しました。 Thxを正しく追加するにはどうすればいいですか? – Rik

+0

また、プレゼンターから関連コードを貼り付けてください。可能であれば、xamlの大きな部分も貼り付けてください。私は、TabControl xamlを貼り付けるDataContext TabControl.soです。 – Nawaz

答えて

0

より多くのコードを見ることなく、プロパティを更新しないようにしていますが、貢献しているかもしれないいくつかの問題があります。

"isIndexFieldSelected"と "isCheckBoxEnabled"の値は、プロパティではなくフィールド名のように見えます。 Bindingにはプロパティが必要ですが、投稿されたコードが与えられているので、問題が発生する場合は、それは明らかではありません。

メニューアイテムをテンプレートする方法によって、各コレクションアイテムに対して2つのMenuItemオブジェクトが作成されます。 ContextMenuは、バインドされたItemsSourceコレクションの各アイテムのMenuItemインスタンスを自動的に生成し、各アイテムのDataTemplateを注入します。 ItemTemplate内でMenuItemを宣言することにより、ContextMenuの各MenuItemのHeaderセクション内にMenuItemを作成しています。データにバインドされていない外部MenuItemをクリックしてチェックしている場合があります。テンプレートとスタイルあなたのために生成されるのMenuItemの両方に代わり、これらのリソースを使用してみてください:

<DataTemplate x:Key="SelectIndexFieldMenuTemplate"> 
    <TextBlock Text="{Binding Path=IndexFieldName}"/> 
</DataTemplate> 

<Style x:Key="SelectIndexFieldMenuStyle" TargetType="{x:Type MenuItem}"> 
    <Setter Property="IsCheckable" Value="True" /> 
    <!--IsChecked is already TwoWay by default--> 
    <Setter Property="IsChecked" Value="{Binding Path=isIndexFieldSelected}" /> 
    <Setter Property="IsEnabled" Value="{Binding Path=isCheckBoxEnabled}" /> 
</Style> 

そして、このようにそれらを使用します。

<TabItem.ContextMenu> 
    <!--TwoWay doesn't ever do anything on ItemsSource--> 
    <ContextMenu Name="menu" ItemsSource="{Binding Path=FieldNameCollection}" 
       ItemContainerStyle="{StaticResource SelectIndexFieldMenuStyle}" 
       ItemTemplate="{StaticResource SelectIndexFieldMenuTemplate}"/> 
</TabItem.ContextMenu> 

それがあなたのバウンドプロパティが正しくINotifyPropertyChangedのを使用していないことも可能ですこれにより、メニュー項目が状態を確認したときにUIが更新されなくなります。

private bool _isIndexFieldSelected; 
public bool isIndexFieldSelected 
{ 
    get { return _isIndexFieldSelected; } 
    set 
    { 
     if (_isIndexFieldSelected == value) 
      return; 
     _isIndexFieldSelected = value; 
     NotifyPropertyChanged("isIndexFieldSelected"); 
    } 
} 

public virtual void NotifyPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventArgs ea = new PropertyChangedEventArgs(propertyName); 
    if (PropertyChanged != null) 
     PropertyChanged(this, ea); 
} 

public event PropertyChangedEventHandler PropertyChanged; 
+0

Thx Johnが応答します。これらの変数はすべて、INotifyPropertyChangeを実装するプロパティです。私は最終的にこれをContextMenu.Resourcesを使って実現しました(以前は2つのメニュー(メニュー付きのメニュー)を生成していました)。そしてメニューの項目ソースから直接プロパティを読み込んでいました。私はそれが正しい方法であれば分かりませんが、それはうまくいきます。 – Rik

関連する問題