Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Context Menu, Copy Menu Item is grayed out

Tags:

c#

.net

wpf

I have a ListView databinded to a ObservableCollection of a class. I'm trying to add a "Copy" menu item to the ListView like so:

    <ListView.ContextMenu>
        <ContextMenu>
            <MenuItem Command="{x:Static ApplicationCommands.Copy}"></MenuItem>
            <MenuItem Command="{x:Static ApplicationCommands.Copy}"
                      CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"></MenuItem>
        </ContextMenu>
    </ListView.ContextMenu>

Now when i right click a menu item.. the menu comes up but the Copy is grayed out.. my educated guess is that it thinks there's nothing for it to copy.. but that doesn't make sense because when i right click a listbox item.. i'm technically selecting something for it to copy.. and the listbox item is selected as i'm doing this..I just want it to copy the selected text in the ListView.

What do I have to do to get this to work? Overwrite a copy class in my class that's binded to the Listview? I tried googling and not getting very far.

like image 544
user1189352 Avatar asked Mar 17 '15 22:03

user1189352


2 Answers

I've just put together an example that works for me:

<Window.CommandBindings>
    <CommandBinding
        Command="ApplicationCommands.Copy"
        CanExecute="CommandBinding_CanExecute"
        Executed="CommandBinding_Executed"/>
</Window.CommandBindings>


<Window.Resources>
    <ContextMenu x:Key="MyContextMenu">
        <MenuItem Header="Copy" Command="ApplicationCommands.Copy"/>
    </ContextMenu>

    <Style x:Key="MyItemContainerStyle" TargetType="{x:Type ListViewItem}">
        <Setter Property="ContextMenu" Value="{StaticResource MyContextMenu}" />
    </Style>
</Window.Resources>

<Grid>
    <ListView x:Name="MyListView" ItemContainerStyle="{StaticResource MyItemContainerStyle}"/>                  
</Grid>

Then in the code behind:

// Test class with a single string property
private class MyData
{
    public String Name { get; set; }

    public MyData(String name)
    {
        Name = name;
    }

    public override string ToString()
    {
        return Name;
    }
}

public MainWindow()
{
    InitializeComponent();

    // Create some test data
    ObservableCollection<MyData> names = new ObservableCollection<MyData>();
    names.Add(new MyData("Name 1"));
    names.Add(new MyData("Name 2"));
    names.Add(new MyData("Name 3"));
    MyListView.ItemsSource = names;
}

private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
   Clipboard.SetText(MyListView.SelectedItem.ToString());
}

This works whether you select Copy from the context menu, or use Ctrl+C

like image 158
Gary Wright Avatar answered Nov 02 '22 00:11

Gary Wright


Without having you rewrite everything, the thing to note about Gary's sample is the presence of a CanExecute statement, which is what controls the enabling/disabling of commands. You should look in to the proper command structure some more, because I think you're missing the real power of the command.

https://msdn.microsoft.com/en-us/library/ms753200%28v=vs.110%29.aspx

like image 43
Graham Bass Avatar answered Nov 02 '22 02:11

Graham Bass