【问题标题】:C# wpf Databinding command not working in contextmenuC# wpf 数据绑定命令在上下文菜单中不起作用
【发布时间】:2017-10-10 18:36:32
【问题描述】:

我正在学习 wpf 和 mvvm,我决定创建一个 Soundboard 供自己练习,目前进展顺利。 现在我制作了一个数据模板,对于程序在指定目录中找到的每个文件,它将创建一个带有文件名的按钮,我可以单击它来播放。到目前为止,一切都很好。 但是,我现在尝试创建一个 ContextMenu,以便当我想从列表中删除文件时,我可以右键单击并选择删除,但即使我对常规按钮具有完全相同的命令结构,此命令也不起作用。

我真的对整个 RelativeSource 感到很困惑,并且已经很高兴我的常规“播放”命令在按钮中起作用了。

如果有人能指出我正确的方向,那就太好了。我真的可以对我的具体问题进行解释,因为这似乎总是比一般的例子更能帮助我。我已尝试阅读所有相关问题,但似乎无法从那里弄清楚。

我的项目控制:

<ItemsControl x:Name="MySounds" ItemsSource="{Binding Sounds}">

项目模板:

<ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Button Style="{StaticResource mainButton}"
                                Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.PlaySound}" 
                                CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
                                Tag="{Binding Path=Name}">
                            <TextBlock Text="{Binding Path=NormalizedName}" TextWrapping="Wrap" Height="auto" />
                            <Button.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Header="{Binding Path=Name}" 
                                              Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.RemoveSound}" 
                                              CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Self}}">
                                        <MenuItem.Icon>
                                            <Image Source="\WpfPractice;component\Images\CoffeeArt.png" Width="20" VerticalAlignment="Center"/>
                                        </MenuItem.Icon>
                                    </MenuItem>
                                </ContextMenu>
                            </Button.ContextMenu>
                        </Button>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>

我的视图模型中有一个通用的 RelayCommand 并且一切正常,问题实际上只是绑定。

【问题讨论】:

  • 您可以尝试使用ElementName 代替RelativeSource 吗?为您的 ItemsControl 设置一个名称(例如 x:Name="myIC"),然后更新您的绑定。
  • 我试过了,但无论我尝试什么,它似乎都不起作用。在我的 MenuItem 标头中,我得到的值与带有 {binding Path=Name} 的按钮中的值相同,但是相同的命令似乎不起作用。

标签: c# wpf mvvm


【解决方案1】:

如果将Button 的Tag 属性绑定到ItemsControl,则可以使用PlacementTarget 的PlacementTarget 属性绑定到命令:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <StackPanel>
            <Button Style="{StaticResource mainButton}"
                                Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.PlaySound}" 
                                CommandParameter="{Binding Path=Name}"
                                Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}">
                <TextBlock Text="{Binding Path=NormalizedName}" TextWrapping="Wrap" Height="auto" />
                <Button.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="{Binding Path=Name}" 
                                  Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.DataContext.RemoveSound}" 
                                  CommandParameter="{Binding Path=Name}">
                            <MenuItem.Icon>
                                <Image Source="\WpfPractice;component\Images\CoffeeArt.png" Width="20" VerticalAlignment="Center"/>
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>
        </StackPanel>
    </DataTemplate>
</ItemsControl.ItemTemplate>

【讨论】:

  • 您能否详细说明为什么以及是什么使这项工作有效?是因为 Tag 现在设置为 RelativeSource ItemsControl,然后 PlacementTarget 设置为 Tag,然后又设置为 DataContext?就像我之前所说的,我对 RelativeSource 的理解非常简单。
  • ContextMenu 位于它自己的可视化树中,因此它没有任何祖先。 Button 有。
【解决方案2】:

您可以尝试通过以下方式替换 MenuItem 中的命令字符串:

Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.RemoveSound}"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 2012-01-01
    • 1970-01-01
    • 2014-12-06
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多