C# Can';t将ContextMenu操作绑定到命令
我已经搜索并阅读了关于ContextMenus和binding的所有内容,以及它如何不在树中。。。等等,所以搜索让我觉得我已经筋疲力尽了,只是不理解它 我正试图让我的ContextMenu AddTournamentCommand运行,但我就是无法让它运行。我最近发现了通过数据源绑定到对象的简单方法,因此,如果有一种简单的方法,而不是手工编码来连接,请告诉我。这就是我到目前为止所做的:C# Can';t将ContextMenu操作绑定到命令,c#,wpf,C#,Wpf,我已经搜索并阅读了关于ContextMenus和binding的所有内容,以及它如何不在树中。。。等等,所以搜索让我觉得我已经筋疲力尽了,只是不理解它 我正试图让我的ContextMenu AddTournamentCommand运行,但我就是无法让它运行。我最近发现了通过数据源绑定到对象的简单方法,因此,如果有一种简单的方法,而不是手工编码来连接,请告诉我。这就是我到目前为止所做的: <Window xmlns="http://schemas.microsoft.com/
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Models="clr-namespace:FumbblApiClient.Models" mc:Ignorable="d" x:Name="FumbblMainWindow" x:Class="FumbblApiClient.MainWindow"
Title="MainWindow" Height="499.45" Width="639" Loaded="Window_Loaded">
<Window.Resources>
<CollectionViewSource x:Key="groupViewSource" d:DesignSource="{d:DesignInstance {x:Type Models:Group}, CreateList=True}"/>
<CollectionViewSource x:Key="groupTournamentsViewSource" Source="{Binding Tournaments, Source={StaticResource groupViewSource}}"/>
</Window.Resources>
<Grid Margin="0,0,2,0">
<TabControl Margin="10">
<TabItem Header="Groups">
<Grid Background="#FFE5E5E5" DataContext="{StaticResource groupViewSource}">
<TextBox x:Name="GroupIdTextBox" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="Group ID" VerticalAlignment="Top" Width="100" Grid.Column="1"/>
<Button Content="Fetch" HorizontalAlignment="Left" Margin="115,11,0,0" VerticalAlignment="Top" Width="61" Click="GroupFetch_Click" Grid.Column="1" Height="22"/>
<ListBox x:Name="groupListView" ItemsSource="{Binding}" Margin="10,38,0,10" SelectionMode="Single" HorizontalAlignment="Left" Width="166" SelectionChanged="GroupList_SelectionChanged">
</ListBox>
<Grid x:Name="grid1" Margin="181,38,10,0" VerticalAlignment="Top" Height="369">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="Id:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/>
<TextBox x:Name="idTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding Id, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
<Label Content="Name:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="1" VerticalAlignment="Center"/>
<TextBox x:Name="nameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="1" Text="{Binding Name, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/>
<Label Content="Tournaments:" HorizontalAlignment="Left" Margin="3" Grid.Row="2" VerticalAlignment="Center"/>
<ListBox x:Name="tournamentsListView" ItemsSource="{Binding Source={StaticResource groupTournamentsViewSource}}" Margin="3,3,-182,-260" SelectionMode="Multiple" Grid.Row="2" Grid.Column="1">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="UIElement.PreviewMouseRightButtonDown" Handler="EmptyHandler"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Add To Selected Tournaments" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=PlacementTarget.DataContext.AddTournamentCommand}"/>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
</Grid>
</Grid>
</TabItem>
<TabItem Header="Tournaments">
<Grid Background="#FFE5E5E5" Margin="0,0,0,-2">
<ListBox HorizontalAlignment="Left" Margin="10,10,0,10" Width="166"/>
</Grid>
</TabItem>
<TabItem Header="Teams">
</TabItem>
<Grid Margin="0,0,-10,10"/>
</TabControl>
</Grid>
</Window>
像这样改变,
<ContextMenu>
<MenuItem Header="Add To Selected Tournaments" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=AddTournamentCommand}"/>
</ContextMenu>
PlacementTarget
属性位于上下文菜单上,而不在窗口上。转到上下文菜单,而不是窗口。无论如何,窗口不在ContextMenu的可视树中,所以您无法使用RelativeSource访问它
<ContextMenu>
<MenuItem Header="Add To Selected Tournaments"
Command="{Binding RelativeSource={RelativeSource
AncestorType={x:Type ContextMenu}},
Path=PlacementTarget.DataContext.AddTournamentCommand}"/>
</ContextMenu>
使用上述代码,您将获得PlacementTarget的dataContext,它将是ListBox的dataContext,如果您没有在ListBox上显式设置dataContext,它将从窗口继承它,您的代码将正常工作
更新
您可以将窗口数据上下文存储在ListBox的标记中,并使用它进行绑定
<ListBox Tag="{Binding DataContext,
RelativeSource={RealtiveSource Mode=FindAncestor,
AncestorType=Window}}"/>
并在ContextMenu中使用标记绑定:
<ContextMenu>
<MenuItem Header="Add To Selected Tournaments"
Command="{Binding RelativeSource={RelativeSource
AncestorType={x:Type ContextMenu}},
Path=PlacementTarget.Tag.AddTournamentCommand}"/>
</ContextMenu>
Lol,与WinForms相比,WPF中的某些东西有多么困难,这仍然让我感到惊讶。在WinForms中,只需单击鼠标左键即可。但树中没有窗口,对吗?这没有约束力。给我:找不到引用为“RelativeSource FindAncestor,AncestorType='System.Windows.Window',AncestorLevel='1'的绑定源。BindingExpression:Path=AddTournamentCommand;DataItem=null;目标元素是“MenuItem”(名称=“”);目标属性为“Command”(类型为“ICommand”),如果在XAML中查找,则列表框确实具有不同的DataContext。我如何绕过它,或者如何在该上下文中获取命令?它绑定到一个对象模型,所以我不太愿意在它上面放一个命令对象。这确实解决了绑定问题。我仍然无法触发这个动作,所以我最后只是做了一个按钮,以避免让自己过于沮丧。
<ContextMenu>
<MenuItem Header="Add To Selected Tournaments"
Command="{Binding RelativeSource={RelativeSource
AncestorType={x:Type ContextMenu}},
Path=PlacementTarget.Tag.AddTournamentCommand}"/>
</ContextMenu>