1
votes

I have to implement a WPF DataGrid with which it is possible to select only cells in one row. How could I achieve this? I know the properties SelectionUnit and SelectionMode but each combination of these two properties did not lead to success.

XAML:

<DataGrid AutoGenerateColumns="True" CanUserAddRows="False" 
    ItemsSource="{Binding DPGridCR}" HeadersVisibility="None" SelectionUnit="Cell"
    SelectionMode="Extended" CanUserResizeRows="False" />

At this moment I am just able to select many cells in many rows or just select one single cell or select a whole row. But I want to select many cells in ONE row.

Edit:

<UserControl x:Class="DesignerPro.Controls.DZLeerformularGrid"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:ViewModel="clr-namespace:ViewModel;assembly=ViewModel"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="300"
    x:Name="DZLeerformularGridControl">

    <UserControl.Resources>
        <ViewModel:DZLeerformularGridViewModel x:Key="ViewModel" />
    </UserControl.Resources>

    <DataGrid AutoGenerateColumns="True" CanUserAddRows="False"
        ItemsSource="{Binding DPGridCR}" HeadersVisibility="None" SelectionUnit="Cell"
        SelectionMode="Extended" CanUserResizeRows="False">

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectedCellsChanged">
                <ei:CallMethodAction TargetObject="{Binding Mode=OneWay, Source={StaticResource ViewModel}}" MethodName="DataGrid_SelectedCellsChanged" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </DataGrid>
</UserControl>

With the EventTrigger I tried to bind the SelectedCellsChanged-Event to my ViewModel. Your solution works fine in the code-behind but in my ViewModel it doesn't work :(

1
Are you using the CTRL key to do the multiple selection?Wyatt Earp
No. I just use the WPF default DataGrid with several SelectionUnit and SelectionMode combinations.Patrick Vogt
What I'm saying is, after you set SelectionUnit="Cell" and SelectionMode="Extended" it should work. But, in order for the multi-select to happen, you need to hold CTRL while you click the cells. (Or, you can click and drag, like Excel) If you want it to operate differently, then you'll need to write some custom code.Wyatt Earp
Your solution doesn't work in the way I like. I want to prevent that a user select cells in more than one row. The user is only allowed to select cells in ONE row. For example: The user select the cells three to seven in row eight. This is allowed but the user should not be able to select cells in row eight AND nine! Is there a smart way to do this?Patrick Vogt

1 Answers

1
votes

Try adding this event handler to the SelectedCellsChanged event in the code-behind:

private void DataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
{
    var grid = sender as DataGrid;

    if (grid == null || !grid.SelectedCells.Any())
        return;

    var row = grid.Items.IndexOf(grid.SelectedCells[0].Item);

    try
    {
        // Disable the event handler to prevent a stack overflow.
        grid.SelectedCellsChanged -= DataGrid_SelectedCellsChanged;

        // If any of the selected cells don't match the row of the first selected cell,
        // undo the selection by removing the added cells and adding the removed cells.
        if (grid.SelectedCells.Any(c => grid.Items.IndexOf(c.Item) != row))
        {
            e.AddedCells.ToList().ForEach(c => grid.SelectedCells.Remove(c));
            e.RemovedCells.ToList().ForEach(c => grid.SelectedCells.Add(c));
        }
    }
    finally
    {
        // Don't forget to re-enable the event handler.
        grid.SelectedCellsChanged += DataGrid_SelectedCellsChanged;
    }
}