c# - 将上下文菜单绑定(bind)到 View 模型属性

标签 c# wpf xaml mvvm

我有一个关联到数据网格中的按钮的上下文菜单。我希望上下文菜单项根据我在 View 模型中拥有的字符串列表进行更改。当我点击按钮时,没有任何显示。

这是我正在使用的 xaml,它位于数据网格中:

<Button Grid.Column="1" Content="..."  Click="Button_Click">
        <Button.ContextMenu>
       <ContextMenu ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}},Path=DataContext.SelectableDescriptions}">    
         <TextBlock Text="{Binding}"/>
       </ContextMenu>
       </Button.ContextMenu>        
</Button>

这是整个 DataGrid xaml:

<DataGrid Grid.Row="1" Grid.ColumnSpan="4" CanUserAddRows="True" AutoGenerateColumns="False" CanUserDeleteRows="True"  ItemsSource="{Binding JobPricings, Mode=TwoWay}" SelectedItem="{Binding SelectedJobPricing, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
    <DataGrid.Columns>
        <DataGridTemplateColumn  Header="Description" Width="25*"   >
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="75*"/>
                            <ColumnDefinition Width="25*"/>
                        </Grid.ColumnDefinitions>
                        <TextBox Grid.Column="0" Text="{Binding Description,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                        <Button Grid.Column="1" Content="..."  Click="Button_Click">
                            <Button.ContextMenu>
                                <ContextMenu ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}},Path=DataContext.SelectableDescriptions}">
                                    <TextBlock Text="{Binding}"/>
                                </ContextMenu>
                            </Button.ContextMenu>
                        </Button>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
         </DataGridTemplateColumn>
        <DataGridTextColumn Header="Unit Price" Binding="{Binding UnitPrice, Mode=TwoWay}" Width="25*"/>
        <DataGridTextColumn Header="Unit" Binding="{Binding Unit, Mode=TwoWay}" Width="25*"/>
        <DataGridTemplateColumn  Header="Currency   " Width="25*" >
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid>
                        <ComboBox  SelectedValue="{Binding CurrencyID, Mode=TwoWay}" SelectedValuePath="ID" DisplayMemberPath="Description" ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}},Path=DataContext.Currencies}"  ></ComboBox>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

这是我通过 View 模型将上下文菜单绑定(bind)到的属性:

public ObservableCollection<string> SelectableDescriptions
{
    get
    {
        _selectableDescriptions.Add("One");
        _selectableDescriptions.Add("Two");
        return _selectableDescriptions;
    }
    set
    {
        _selectableDescriptions = value;
    }
}

关于为什么我的列表不会显示在上下文菜单中的任何想法?

最佳答案

正如 John 所说,ContextMenu 是它自己的独立窗口,与按钮的可视化树分开,因此它不会自动继承按钮的 DataContext

但是,ContextMenu 确实有一个链接指向它所在的对象(在您的例子中是按钮):PlacementTarget。通过转到菜单的 PlacementTarget,您可以找到该按钮,找到该按钮后,您可以找到它的 DataContext。

因此,在 xaml 中,您可以通过将自己的 DataContext 绑定(bind)到自己的 PlacementTarget.DataContext 以及所有其他绑定(bind)(例如,对于ItemsSource) 可以正常写成:

<Button Grid.Column="1" Content="..."  Click="Button_Click">
    <Button.ContextMenu>
        <ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.DataContext}" 
                     ItemsSource="{Binding Path=SelectableDescriptions}" >    
            <ContextMenu.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=SomePropertyOnItem}" />
                </DataTemplate>
            </ContextMenu.ItemTemplate>                            
        </ContextMenu>
    </Button.ContextMenu>        
</Button>

关于c# - 将上下文菜单绑定(bind)到 View 模型属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14587293/

相关文章:

java - 改造具有空字段的获取对象

c# - 组合框 isEditablelostFocus 在获得焦点时调用

c++ - 访问呈现的 WPF 页面/窗口的底层 DirectX 表面/渲染目标

wpf - 将 TabControl 与分组的 CollectionViewSource 结合使用

从 RSS 提要获取特定数据的 C# 单行代码

java - 如何在不测试调用数据库的私有(private)方法的情况下进行单元测试

c# - UDP端口开放检查

c# - 如何将 ObservableCollections 绑定(bind)到 ItemsSource?

wpf - 如何调用在 Powershell 中另一个运行空间中运行的 WPF 表单元素的方法

c# - 在'System.Windows.StaticResourceExtension 上提供值(value)