WPF DataGrid - выбор полной строки - PullRequest
12 голосов
/ 02 апреля 2011

Я использую WPF и .NET 4.0.Недавно в одной из моих программ я перешел от использования ListView с GridView к DataGrid.

Я хочу иметь возможность выбирать и выделять всю строку, как я мог сделать в ListView.

ВListView, когда я нажимаю на пустое место справа от последнего столбца, я все еще могу выбрать строку.Подсвечивается вся строка, а не только ячейки.

Однако в DataGrid после установки SelectionMode = "Single" и SelectionUnit = "FullRow" строка выбирается только при нажатии на любую ячейку в ней, а нев пустом месте справа от последнего столбца.

Как я могу использовать поведение подсветки из ListView здесь?

Ответы [ 3 ]

9 голосов
/ 02 апреля 2011

Существует два решения:

  1. Установите для ширины последнего столбца в DataGrid значение Width = "*".
  2. Второе решение - это обходной путь.Добавьте дополнительный пустой столбец после последнего столбца (т. Е. Не устанавливайте его свойства Header или Binding) и установите для его ширины значение Width = "*"

Я лично предпочитаю первое решение, оно более чистое, чем второеодин.

1 голос
/ 27 мая 2016

Основываясь на предыдущем комментарии Алексея Л., вот решение с классом DataGridBehavior с FullRowSelect свойством зависимости.

Поведение автоматически присоединит обработчик события MouseDown.Кроме того, он установит « SelectionMode = DataGridSelectionMode.Single », поэтому он будет правильно работать с привязками DataContext и SelectedItem .

XAML

<UserControl x:Class="WpfDemo.Views.Default"
         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:b="clr-namespace:WpfDemo.Behaviors"
         mc:Ignorable="d" 
         d:DesignHeight="300">

        <DataGrid b:DataGridBehavior.FullRowSelect="True">
              ...
        </DataGrid>             

Класс DataGridBehavior

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfDemo.Behaviors
{
    /// <summary>
    /// Extends <see cref="DataGrid"/> element functionality.
    /// </summary>
    public static class DataGridBehavior
    {
        #region - Dependency properties -

        /// <summary>
        /// Forces row selection on empty cell, full row select.
        /// </summary>
        public static readonly DependencyProperty FullRowSelectProperty = DependencyProperty.RegisterAttached("FullRowSelect",
            typeof(bool),
            typeof(DataGridBehavior),
            new UIPropertyMetadata(false, OnFullRowSelectChanged));

        #endregion

        #region - Public methods -

        /// <summary>
        /// Gets property value.
        /// </summary>
        /// <param name="grid">Frame.</param>
        /// <returns>True if row should be selected when clicked outside of the last cell, otherwise false.</returns>
        public static bool GetFullRowSelect(DataGrid grid)
        {
            return (bool)grid.GetValue(FullRowSelectProperty);
        }

        /// <summary>
        /// Sets property value.
        /// </summary>
        /// <param name="grid">Frame.</param>
        /// <param name="value">Value indicating whether row should be selected when clicked outside of the last cell.</param>
        public static void SetFullRowSelect(DataGrid grid, bool value)
        {
            grid.SetValue(FullRowSelectProperty, value);
        }

        #endregion

        #region - Private methods -

        /// <summary>
        /// Occurs when FullRowSelectProperty has changed.
        /// </summary>
        /// <param name="depObj">Dependency object.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnFullRowSelectChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = depObj as DataGrid;
            if (grid == null)
                return;

            if (e.NewValue is bool == false)
            {
                grid.MouseDown -= OnMouseDown;

                return;
            }

            if ((bool)e.NewValue)
            {
                grid.SelectionMode = DataGridSelectionMode.Single;

                grid.MouseDown += OnMouseDown;
            }
        }

        private static void OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            var dependencyObject = (DependencyObject)e.OriginalSource;

            while ((dependencyObject != null) && !(dependencyObject is DataGridRow))
            {
                dependencyObject = VisualTreeHelper.GetParent(dependencyObject);
            }

            var row = dependencyObject as DataGridRow;
            if (row == null)
            {
                return;
            }

            row.IsSelected = true;
        }

        #endregion
    }
}
1 голос
/ 18 августа 2013

Существует еще одно решение, если вы можете использовать код позади в своем проекте. Вы можете обработать событие нажатия мыши на сетке данных и программно выбрать строку, по которой щелкнули:

 private void SomeGridMouseDown(object sender, MouseButtonEventArgs e)
    {
        var dependencyObject = (DependencyObject)e.OriginalSource;

        //get clicked row from Visual Tree
        while ((dependencyObject != null) && !(dependencyObject is DataGridRow))
        {
            dependencyObject = VisualTreeHelper.GetParent(dependencyObject);
        }

        var row = dependencyObject as DataGridRow;
        if (row == null)
        {
            return;
        }

        row.IsSelected = true;
    }
...