Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF items控件在上下文菜单中获取绑定对象的简单示例';s单击处理程序_C#_Wpf_Data Binding - Fatal编程技术网

C# WPF items控件在上下文菜单中获取绑定对象的简单示例';s单击处理程序

C# WPF items控件在上下文菜单中获取绑定对象的简单示例';s单击处理程序,c#,wpf,data-binding,C#,Wpf,Data Binding,我使用的是.NETCore3.1WPF 问题1。在项目模板内部定义是否是推荐的方法?例如,如果有100个项目,这难道不会创建100个不可见的上下文菜单吗 问题2。如果在项目模板内部定义是无效的,我希望避免像这样定义,因为如果用户右键单击一个空(没有项目)区域,将显示上下文菜单。在父控件中定义一个似乎很有效,但是现有问题的源代码有点太复杂了,我无法让它工作 下面是一个简单的示例代码。如何在关联菜单中单击事件showbride,获取绑定到StackPanel的Dog对象 <Window x:C

我使用的是.NETCore3.1WPF

问题1。在项目模板内部定义
是否是推荐的方法?例如,如果有100个项目,这难道不会创建100个不可见的上下文菜单吗

问题2。如果在项目模板内部定义
是无效的,我希望避免像这样定义
,因为如果用户右键单击一个空(没有项目)区域,将显示上下文菜单。在父控件中定义一个
似乎很有效,但是现有问题的源代码有点太复杂了,我无法让它工作

下面是一个简单的示例代码。如何在关联菜单中单击事件
showbride
,获取绑定到
StackPanel
Dog
对象

<Window x:Class="deletewpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="600">

    <ItemsControl Name="DogList">
        <ItemsControl.Resources>
            <ContextMenu x:Key="ItemContextMenu"
                         DataContext="{Binding PlacementTarget.Tag}">
                <MenuItem Click="ShowBreed" CommandParameter="{Binding}" >Show Breed</MenuItem>
            </ContextMenu>
        </ItemsControl.Resources>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel ContextMenu="{StaticResource ItemContextMenu}"
                            Tag="{Binding DataContext}">
                    <TextBlock FontSize="30pt" Text="{Binding Name}"/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

展示品种
代码隐藏

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        var dogs = new List<Dog>();
        dogs.Add(new Dog { Name = "Dog1", Breed = "Shiba" });
        dogs.Add(new Dog { Name = "Dog2", Breed = "Corgi" });
        DogList.ItemsSource = dogs;
    }

    private void ShowBreed(object sender, RoutedEventArgs e)
    {
        Dog d;
        //MessageBox.Show(d.Breed);
    }
}

class Dog
{
    public string Name { get; set; }
    public string Breed { get; set; }
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
var dogs=新列表();
添加(新狗{Name=“Dog1”,Breed=“Shiba”});
添加(新狗{Name=“Dog2”,Breed=“Corgi”});
DogList.ItemsSource=狗;
}
私有void showbride(对象发送方、路由目标方)
{
狗d;
//MessageBox.Show(d.Breed);
}
}
班犬
{
公共字符串名称{get;set;}
公共字符串{get;set;}
}

问题1:我相信这取决于您的场景,如果您需要为每个项目提供一个单独的上下文菜单,那么这可能是必要的,否则您通过使用ressource实现的方式是完美的。 如果每个项目需要单独的资源,可以将
x:Shared=“False”
添加到资源中

我不认为你提到的第三个问题()一定更有效,它只是有不同的要求

问题2:我认为你混淆了三个不同的问题,它们有不同的目标,但没有完全理解答案,这导致了一些混乱。您没有解释您试图实现的目标,而是在示例中回答以下问题:

<ItemsControl Name="DogList">
    <ItemsControl.Resources>
        <ContextMenu x:Key="ItemContextMenu" >
            <MenuItem Click="ShowBreed">Show Breed</MenuItem>
        </ContextMenu>
    </ItemsControl.Resources>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel x:Name="PlacementTarget" ContextMenu="{StaticResource ItemContextMenu}">
                <TextBlock FontSize="30pt" Text="{Binding Name}"/>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
如前所述,您在引用的答案中混合了以下几点: 在第一个例子中,问题是如何绑定到viewModel而不是item,可接受的答案是将按钮的Tag属性设置为ItemControl的DataContext,然后从ContextMenu绑定到它。 在您提供的示例中,这不是您想要的。您希望访问dog对象,它是项目的默认Datacontext,因此不需要更改任何内容

如果不实际使用命令,则不需要在此处使用
CommandParameter=“{Binding}”
。ClickEvent不使用此选项


旁注:绑定到Datacontext的语法实际上是
{Binding}
,而不是
{Binding Datacontext}
,后者试图访问绑定源的“Datacontext”属性(默认情况下为Datacontext)。如果您检查您引用的第一个答案,您将看到源代码也在绑定中设置(
Tag=“{Binding DataContext,RelativeSource={RelativeSource AncestorType=ItemsControl}}”

谢谢。当XAML变得复杂时,就很难理解/读取它,比如
DataContext=“{Binding DataContext,RelativeSource={RelativeSource anstortype={x:Type UserControl}}}”
。我不知道嵌套的相对资源到底是什么意思。类似于
DataContext=“{Binding PlacementTarget.Tag}”
CommandParameter=“{Binding}”
的内容来自现有答案。当我在网页上搜索ItemControls上下文菜单时,复杂的答案显示在顶部,所以我认为它会如此复杂。我不知道我根本不需要
菜单项中的任何东西来获取数据。我不能不同意这一点。你只需要练习和测试不同的场景,直到感觉更自然。Datacontext背后的概念是最重要的IMHO。问题1和2是相关的。根据问题1的答案,问题2是不必要的(因为问题1中的方法可以完成任务,而没有问题2中的方法)。
private void ShowBreed(object sender, RoutedEventArgs e)
    {
        //The sender is the MenuItem which was clicked and its DataContext is the item (dog in the exemple)
        Dog d = ((MenuItem)sender).DataContext as Dog;
        MessageBox.Show(d.Breed);
    }