Home > Blockchain >  Show ContextMenu only when Right clicked mouse is over on a specific datagridrow WPF C#
Show ContextMenu only when Right clicked mouse is over on a specific datagridrow WPF C#

Time:12-11

I have a Page with a datagrid --> xaml code below:

    <DataGrid x:Name="DataGrid" 
    IsReadOnly="True"
    AutoGenerateColumns="False" 
    SelectionUnit="FullRow" 
    BorderBrush="{x:Null}" 
    HorizontalContentAlignment="Stretch"
    ColumnWidth="Auto" Focusable="False" 
    MouseDoubleClick="DataGridArticoli_MouseDoubleClick" 
    GridLinesVisibility="None" 
    HeadersVisibility="Column" 
    UseLayoutRounding="False" 
    SelectionChanged="DataGrid_SelectionChanged">

    <!--Columns-->
    <DataGrid.Columns>
        <DataGridTextColumn col_1/>
        <DataGridTextColumn col_2/>
        <DataGridTextColumn col_3/>
        <DataGridTextColumn col_4/>
        <DataGridTextColumn col_5/>
        <DataGridTextColumn col_6/>
        <DataGridTextColumn col_7/>
        <DataGridTextColumn col_8/>
        <DataGridTextColumn col_9/>
        <DataGridTextColumn col_10/>
    </DataGrid.Columns>
    
    <DataGrid.ContextMenu>
        <ContextMenu x:Name="ContextMenu">
            <MenuItem Header="Remove" Click="Remove_ContextMenuClick">
                <MenuItem.Icon>
                    <Image Source="/resources/delete.png"/>
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem x:Name="btnOpen" Header="Open" Click="Open_ContextMenuClick" IsEnabled="False">
                <MenuItem.Icon>
                    <Image Source="/resources/open.png"/>
                </MenuItem.Icon>
            </MenuItem>
        </ContextMenu>
    </DataGrid.ContextMenu>
    
</DataGrid>

In this case context menu appear in each position of the mouse (when right clicked). I want show the context menu only in the selected row and only when mouse pointer is over the row selected. I tried different solutions, but I didn't find the right one. Someone can help me with some example code?

CodePudding user response:

You could use a RowStyle with a Trigger:

<DataGrid x:Name="DataGrid"  ...>

    <DataGrid.Resources>
        <ContextMenu x:Key="ContextMenu">
            <MenuItem Header="Remove" Click="Remove_ContextMenuClick">
                <MenuItem.Icon>
                    <Image Source="/resources/delete.png"/>
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem x:Name="btnOpen" Header="Open" Click="Open_ContextMenuClick" IsEnabled="False">
                <MenuItem.Icon>
                    <Image Source="/resources/open.png"/>
                </MenuItem.Icon>
            </MenuItem>
        </ContextMenu>
    </DataGrid.Resources>

    <DataGrid.Columns>
        ...
    </DataGrid.Columns>

    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="ContextMenu" Value="{StaticResource ContextMenu}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </DataGrid.RowStyle>

</DataGrid>

CodePudding user response:

I have in this case, a DataGrid style file is linked at application level. How can I insert the trigger in the Datagrid Style? I put below the code block in reference at DataGridRow -->

    <Style TargetType="{x:Type DataGridRow}">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="MinHeight" Value="30"/>
    <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
    <Setter Property="ValidationErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <TextBlock Foreground="Red" Margin="2,0,0,0" Text="!" VerticalAlignment="Center"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridRow}">
                <Border x:Name="DGR_Border" 
                        BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}" 
                        Background="{TemplateBinding Background}" 
                        SnapsToDevicePixels="True">
                    
                    <SelectiveScrollingGrid>
                        <SelectiveScrollingGrid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </SelectiveScrollingGrid.ColumnDefinitions>
                        <SelectiveScrollingGrid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </SelectiveScrollingGrid.RowDefinitions>
                        <DataGridCellsPresenter Grid.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        <DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Visibility="{TemplateBinding DetailsVisibility}"/>
                        <DataGridRowHeader Grid.RowSpan="2" SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                    </SelectiveScrollingGrid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>        
    
    <Style.Triggers>
        <Trigger Property="IsNewItem" Value="True">
            <Setter Property="Margin" Value="{Binding NewItemMargin, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
        </Trigger>
    </Style.Triggers>
</Style>

Then, I should to control the <MenuItem x:Name="btnOpen" inside .cs code. I want to deactivate the button open if I select more than one row, and activate btnOpen inside the ContextMenu dynamically when I select one row.

  • Related