Drag selecting/partially selecting cell content of DataGridTextColumn WPF DataGrid

StashyCode 61 Reputation points
2021-11-03T17:37:04.213+00:00

I have a DataGrid as such:

<DataGrid  
    Name="Employees"  
    AutoGenerateColumns="True"   AutoGeneratingColumn="Employees_AutoGeneratingColumn"  
    EnableColumnVirtualization="True"  
    EnableRowVirtualization="True"  
    IsReadOnly="True"  
    ItemsSource="{Binding EmployeesDataTable}"  
    KeyboardNavigation.TabNavigation="Once"  
    SelectionUnit="CellOrRowHeader"   VirtualizingPanel.VirtualizationMode="Recycling" />  

All the autogenerated columns in the DataGrid are DataGridTextColumns.

I want to be able to select just a part of the cell, not the whole cell (so called drag select).

What is the correct approach to that?

EDIT:

I tried the following approach:

  • Setting the IsReadOnly property of the DataGrid to False
  • Setting EditingElementStyle of the DataGridTextColumns: <Style TargetType="TextBox">
    <Setter Property="IsReadOnly" Value="True" />
    </Style>

This way, I can select part of the cell content, BUT I have to double-click on it (for it to enter CellEditing mode) and I don't want to do that.

I also tried adding:

<Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
               <Setter Property="Background" Value="{x:Null}" />
               <Setter Property="BorderBrush" Value="{x:Null}" />
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
              <Setter Property="IsEditing" Value="True" />
        </Trigger>
 </Style.Triggers>

Which kinda works, but when I move my mouse, the selection is lost, which is pretty annoying.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,667 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
762 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Hui Liu-MSFT 38,026 Reputation points Microsoft Vendor
    2021-11-04T06:22:48.357+00:00

    The DataGridTextColumn is behaving the same whether it is autogenerated or not. You are setting IsReadOnly = True. This may be one of the reasons why it behaves like you described. You could try to delete IsReadOnly="True" or set IsReadOnly="False".

    Update:

    <DataGrid Name="Employees" Height="200"  
                   AutoGenerateColumns="False" IsReadOnly="True"   
                   EnableColumnVirtualization="True"   
                   EnableRowVirtualization="True"  
                   ItemsSource="{Binding EmployeesDataTable}"  
                  SelectionUnit="CellOrRowHeader"  
                   VirtualizingPanel.VirtualizationMode="Recycling">  
                <DataGrid.Columns>  
                    <DataGridTemplateColumn>  
                        <DataGridTemplateColumn.CellTemplate>  
                            <DataTemplate>  
                                <TextBox IsReadOnly="True" Text="{Binding Name}"/>  
                            </DataTemplate>  
                        </DataGridTemplateColumn.CellTemplate>  
                    </DataGridTemplateColumn>  
                </DataGrid.Columns>  
            </DataGrid>  
    

    If the answer is the right solution, please click Accept Answer and kindly upvote it. If you have extra questions about this answer, please click Comment.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. mm8 1 Reputation point MVP
    2021-11-04T19:13:44.323+00:00

    If the columns are auto-generated, you could handle the AutoGeneratingColumn event and replace the DataGridTextColumns with DataGridTemplateColumns:

    private void Employees_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        e.Column = new DataGridTemplateColumn()
        {
            Header = e.Column.Header,
            SortMemberPath = e.PropertyName,
            CellTemplate = XamlReader.Parse("<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">" +
            "<TextBox Background=\"Transparent\" IsReadOnly=\"True\" TextWrapping=\"Wrap\" BorderThickness=\"0\" " +
            $"Text=\"{{Binding {e.PropertyName}}}\"/>" +
            "</DataTemplate>") as DataTemplate
        };
    }
    
    0 comments No comments