WPF上下文菜单数据绑定

时间:2010-12-14 15:57:32

标签: wpf xaml binding

我正在尝试将tab的上下文菜单(带复选框)绑定到observable collection。当用户第一次检查或取消选择菜单项时,该状态会反映在中 obesarvable集合中的关联bool变量。但在那之后它没有反映出来。 XAML中的绑定如下所示:

        <TabItem.ContextMenu>
            <ContextMenu Name="menu"
                         ItemsSource="{Binding Path=FieldNameCollection,Mode=TwoWay}"
                         ItemTemplate="{StaticResource SelectIndexFieldMenu}"></ContextMenu>
        </TabItem.ContextMenu>

数据模板

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

(我无法添加代码段,所以我删除了'&lt;':() 可观察集合的类派生自NotifierBase。 我注意到的另一件事是,如果我在ContextMenuClosing中查看view.xaml.cs中的上下文菜单的itemsource,则会正确反映状态。

1 个答案:

答案 0 :(得分:0)

如果没有看到更多代码导致属性不更新的原因尚不清楚,但有一些问题可能会有所帮助。

“isIndexFieldSelected”和“isCheckBoxEnabled”值看起来像字段名而不是属性。如果是这种情况会导致问题,因为Binding需要属性但是给出了发布的代码,它不清楚。

您模板化菜单项的方式将导致为每个集合项创建两个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;