无法将ContextMenu操作绑定到Command

时间:2014-03-24 03:02:54

标签: c# wpf

我已经搜索并阅读了有关ContextMenus和绑定的任何内容,以及它是如何不在树中的...等等。所以搜索感觉就像我已经筋疲力尽而且只是#&# 39;理解它。

我试图让我的ContextMenu AddTournamentCommand工作,但我根本无法让它命令。我最近发现了通过数据源绑定到对象的简单方法,所以如果有一种简单的方法,而不是手动编码来连接它,请告诉我。这就是我到目前为止所做的:

<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>

并在守则背后:

public partial class MainWindow : Window
{
    [removed]

    private ICommand addTournamentCommand;
    public ICommand AddTournamentCommand
    {
        get
        {
            if(addTournamentCommand == null)
            {
                addTournamentCommand = new RelayCommand(OnTournamentAdded);
            }

            return addTournamentCommand;
        }
    }

    private void OnTournamentAdded(object state)
    {

    }
}

2 个答案:

答案 0 :(得分:2)

PlacementTarget属性位于Context Menu而非窗口。前往ContextMenu而不是Window。窗口无论如何都不在ContextMenu的Visual Tree中,所以你无法使用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,它将从Window继承它,您的代码将正常工作


<强>更新

您可以将Window DataContext存储在ListBox的Tag中并与之绑定

<ListBox Tag="{Binding DataContext,
               RelativeSource={RealtiveSource Mode=FindAncestor, 
                              AncestorType=Window}}"/>

并使用Tag:

在ContextMenu中绑定
<ContextMenu>
   <MenuItem Header="Add To Selected Tournaments"
             Command="{Binding RelativeSource={RelativeSource
                               AncestorType={x:Type ContextMenu}},
                        Path=PlacementTarget.Tag.AddTournamentCommand}"/>
</ContextMenu>

答案 1 :(得分:0)

像这样改变,

 <ContextMenu>
    <MenuItem Header="Add To Selected Tournaments" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=AddTournamentCommand}"/>
  </ContextMenu>