简体   繁体   English

无法将ContextMenu操作绑定到Command

[英]Can't bind a ContextMenu action to a Command

I've searched and read anything I can about ContextMenus and binding, and how it's not in the tree... etc. So searching feels like I've exhausted it and just don't understand it. 我已经搜索并阅读了关于ContextMenus和绑定的任何内容,以及它是如何不在树中的......等等。所以搜索感觉就像我已经筋疲力尽而只是不理解它。

I'm trying to get my ContextMenu AddTournamentCommand to work, but I simply can't get it to command. 我正在尝试让我的ContextMenu AddTournamentCommand工作,但我根本无法让它命令。 I recently found out the easy way through Data Sources to bind to objects, so if there's an easy way other than coding it by hand to wire it up, please let me know. 我最近发现了通过数据源绑定到对象的简单方法,所以如果有一种简单的方法,而不是手动编码来连接它,请告诉我。 This is what I have so far: 这是我到目前为止:

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

and in the Code Behind: 并在守则背后:

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

    }
}

PlacementTarget property is on Context Menu and not on window. PlacementTarget属性位于“ Context Menu ,而不在窗口中。 Travel to ContextMenu and not to Window. 前往ContextMenu而不是Window。 Window anyhow doesn't lies in Visual Tree of ContextMenu so you can't reach to it using RelativeSource. 无论如何,窗口不在于ContextMenu的Visual Tree中,因此您无法使用RelativeSource访问它。

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

With above code you will get PlacementTarget's dataContext which will be ListBox's DataContext and if you haven't set explicitly DataContext on ListBox, it will inherit it from Window and your code will work fine. 使用上面的代码,你将获得PlacementTarget的dataContext,这将是ListBox的DataContext,如果你没有在ListBox上显式设置DataContext,它将从Window继承它,你的代码将正常工作。


UPDATE UPDATE

You can store the Window DataContext in Tag of ListBox and bind with it . 您可以将Window DataContext存储在ListBox的Tag中并与之绑定

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

and in ContextMenu bind using Tag: 并在ContextMenu中使用Tag进行绑定:

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

Change like this, 像这样改变,

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM