Kevin Quiring
Kevin Quiring

Reputation: 649

In WPF, How to get a Command Parameter from a specific item in a Collection View Source that is bound to a ListView?

My Goal: Right click on a specific item in my ListView, a context menu pops up, select a command, followed by me running a function based on which item's context menu was selected.

My ListView's ItemsSource is bounded to a CollectionViewSource, whose source is an ObservableCollection of "Items". (ListView, binds -> CollectionViewSource, source -> ObservableCollection of class "Item")

What I tried to do is add a general ContextMenu to all of the "Items" in the listview, and when the context menu item is selected for an item in the ListView, then a command is run. I was able to get the command to run in general, but I haven't been able to get any information/parameters about the specific item whose context menu was chosen.

In this example, "Item" class has a string called host, and I want to pass host string to the RefundRequestCommand but I havent been able to pass any CommandParameters.

I've read some stuff about creating a data template and using that, but haven't been successful. Can anyone guide me / help me out?

Here is some code for reference:

ListView:

<ListView x:Name="ordersList" Margin="0,10,10,0" BorderThickness="2" Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" HorizontalAlignment="Stretch" ItemsSource="{Binding Source={StaticResource cvsOrders}}" SelectionChanged="ordersList_SelectionChanged" SelectedIndex="0" SelectionMode="Extended">
            <ListView.Resources>
                <local:RefundRequestCommand x:Key="refund"></local:RefundRequestCommand>
            </ListView.Resources>
            <ListView.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="test" Command="{StaticResource refund}" CommandParameter="{Binding host}"></MenuItem>
                </ContextMenu>
            </ListView.ContextMenu>
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="140">
                        <GridViewColumnHeader Name="OrderNumber" Click="sortClick" Tag="orderNumber" Content="Order Number" />
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding orderNumber}" TextAlignment="Center"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
        //On and On.....

Command:

class RefundRequestCommand : ICommand
{
    TreeViewFilter treeViewFilter;

    public void Execute(object parameter)
    {
        string host = (string)parameter;
        Console.WriteLine(host);  //FOR TESTING
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;
}

Upvotes: 0

Views: 1897

Answers (1)

D J
D J

Reputation: 7028

Actually you are setting the ContextMenu for ListView but you want to pass ListViewItem over there. You should set the context menu for ListViewItem. Try this.

<local:RefundRequestCommand x:Key="refund"/>

    <Style x:Key="MyLVItemStyle" TargetType="ListViewItem">
        <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu>
                    <MenuItem Header="test" 
                              Command="{StaticResource refund}" 
                              CommandParameter="{Binding host}">
                    </MenuItem>
                </ContextMenu>
            </Setter.Value>
        </Setter>
    </Style>

and use it it you listview like

  <ListView x:Name="ordersList" Margin="0,10,10,0" BorderThickness="2" Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" HorizontalAlignment="Stretch" 
              ItemsSource="{Binding Rectangles}" SelectedIndex="0" SelectionMode="Extended" ItemContainerStyle="{StaticResource MyLVItemStyle}">
......

Also you remove the style applied in ListView and it should work.

Upvotes: 0

Related Questions