WPF Datagrid: при загрузке, выбор текущего элемента (выделение) - PullRequest
6 голосов
/ 05 марта 2011

У меня есть WPF Datagrid, привязанный к некоторым свойствам в моей ViewModel

<DataGrid AutoGenerateColumns="False" Name="dataGrid" SelectionMode="Single"
          ItemsSource="{Binding ItemList}" SelectedItem="{Binding SelectedItem}">
...
</DataGrid>

Когда мое окно загружается и Datagrid тоже, я устанавливаю SelectedItem, и он отлично связывается, но строка не подсвечивается,В тот момент, когда я нажимаю на строку, строка выделяется, и проблема решается.

Как установить / запустить подсветку SelectedItem в сетке данных при загрузке / инициализации?

РЕДАКТИРОВАТЬ:

Это на самом деле выбранопотому что у меня есть маленькая ячейка выбора.Это просто рендеринг выделения, который не срабатывает.

enter image description here

Ответы [ 5 ]

7 голосов
/ 24 мая 2011

У меня была та же самая "проблема" и, наконец, я нашел довольно хорошее решение проблемы.Как вы уже сказали, не то, что строка не выделена, а в том, что она не выделяет строку.Если вы внимательно посмотрите, вы заметите, что когда вы щелкаете в любом месте строки (с помощью мыши), она все равно не выделяет строку, а только ячейки внутри нее.

Так 2 варианта;

  • Создайте код для выбора ячеек строки
  • или создайте Style.Trigger для выделения строки (что, на мой взгляд, является лучшим вариантом).

Чтобы сделать это, добавьте что-то подобное в сетку данных в xaml-файле:

            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow">
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="DodgerBlue"/>
                            <Setter Property="Foreground" Value="White"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.RowStyle>

Надеюсь, это поможет!

Приветствия, LTB

7 голосов
/ 05 марта 2011

При использовании модели в качестве DataContext для окна WPF событие DataGrid SelectionChanged не вызывается до тех пор, пока не будет загружено окно, поэтому строка никогда не подсвечивается, и вы видите только первую строку с частичнымизюминка.Может быть более элегантный способ, но здесь есть обходной путь.

В загруженном событии окна или загруженном событии DataGrid сбросьте привязку SelectedItem:

public MainWindow()
{
    InitializeComponent(); 
    this.Loaded += new RoutedEventHandler( OnLoaded );
}

// could also be placed in the DataGrid's loaded event handler
private void OnLoaded( object sender, RoutedEventArgs e )
{
    if( dataGrid != null && Model.SelectedItem != null )
    {
        var selected = Model.SelectedItem;
        Model.SelectedItem = null;
        Model.SelectedItem = selected;
    }
}

Вот полная работаобразец.

XAML

<Window x:Class="WpfDataGridHighlightOnLoad.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:model="clr-namespace:WpfDataGridHighlightOnLoad" 
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <model:MainWindowModel x:Name="Model" />
    </Window.DataContext>

    <Grid>
        <DataGrid AutoGenerateColumns="True" SelectionMode="Single"
                  HorizontalAlignment="Stretch" 
                  Name="dataGrid" 
                  VerticalAlignment="Top"
                  ItemsSource="{Binding ItemList}"
                  SelectedItem="{Binding SelectedItem}">
        </DataGrid>

        <Button Content="Cycle Selection" Click="OnCycleClick" 
                Height="23" 
                HorizontalAlignment="Right" 
                Name="button1" 
                VerticalAlignment="Bottom" Width="125" />

        <Button Content="Reset Grid" Click="OnResetClick" 
                Height="23" 
                HorizontalAlignment="Left" 
                Name="button2" 
                VerticalAlignment="Bottom" Width="125" />

    </Grid>
</Window>

Код сзади

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;

namespace WpfDataGridHighlightOnLoad
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();   
            this.Loaded += new RoutedEventHandler( OnLoaded );
        }

        // could also be placed in the DataGrid's loaded event handler
        private void OnLoaded( object sender, RoutedEventArgs e )
        {
            if( dataGrid != null && Model.SelectedItem != null )
            {
                var selected = Model.SelectedItem;
                Model.SelectedItem = null;
                Model.SelectedItem = selected;
            }
        }

        private void OnCycleClick( object sender, RoutedEventArgs e )
        {
            int index = Model.ItemList.IndexOf( Model.SelectedItem );
            index = index == Model.ItemList.Count - 1 ? 0 : index + 1;
            Model.SelectedItem = Model.ItemList[index];
        }

        private void OnResetClick( object sender, RoutedEventArgs e )
        {
            Model.Reset();
        }
    }

    public class MainWindowModel : INotifyPropertyChanged
    {
        public MainWindowModel()
        {
            Reset();
        }

        public void Reset()
        {
            ItemList = new List<Person>
                           {
                               new Person("Joe", 20),
                               new Person("John", 30),
                               new Person("Jane", 40),
                               new Person("Jill", 50),
                               new Person("Fido", 7),
                           };

            SelectedItem = ItemList[2];
        }

        private Person _selectedItem;
        public Person SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                NotifyPropertyChanged( "SelectedItem" );
            }
        }

        private List<Person> _itemList;
        public List<Person> ItemList
        {
            get { return _itemList; }
            set
            {
                _itemList = value;
                NotifyPropertyChanged( "ItemList" );
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged( String info )
        {
            if( PropertyChanged != null )
            {
                PropertyChanged( this, new PropertyChangedEventArgs( info ) );
            }
        }

        #endregion
    }

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Person( string name, int age )
        {
            Name = name;
            Age = age;
        }

        public override string ToString()
        {
            return Name;
        }
    }
}
0 голосов
/ 23 июля 2018

Я знаю, что эта ветка очень старая, но ни одно из решений не помогло мне.

Если у кого-то возникла такая же проблема, очень простое решение, которое я нашел, было просто установить фокус наСетка данных перед установкой выбранного элемента под нагрузкой.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    dataGrid.Focus();
    // Set selected item in datagrid
}
0 голосов
/ 03 июля 2017

Произошла ошибка при вставке фиктивных данных в WPF DataGrid, а затем при попытке изменить порядок строк.Подсветка ряда выделена (изображение ниже).

Причина - вставка одного и того же объекта записи несколько раз.

enter image description here

//Ex: Messes up highlighting.    
grid.Items.Add(rowObj);
grid.Items.Add(rowObj);
grid.Items.Add(rowObj);

//Ex: Highlighting OK.  Create a new object each time.  Even if all columns have exact same values.  
rowobj = new .....
grid.Items.Add(rowObj);

rowobj = new .....
grid.Items.Add(rowObj);
0 голосов
/ 26 мая 2017

Это немного старый, но ни один из ответов ни в одном посте, кажется, не совсем правильно. Вы хотите, чтобы он работал так, как он должен был работать: то есть выделение является одинаковым независимо от того, был ли когда-либо элемент управления сфокусирован (что выглядит как нечто случайное).

Это можно сделать в стиле DataGridRow, но хитрость заключается не в том, чтобы указать цвета самостоятельно, а в использовании цветов по умолчанию, поэтому все просто работает. Дополнительное раздражение вызвано тем, что подсвечиваются не ячейки, а ячейки, поэтому вам в основном нужно продублировать стиль выделения ячейки:

<Style
    x:Key="DataGridRowStyle"
    TargetType="{x:Type DataGridRow}">
    <Style.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition
                    Property="IsKeyboardFocusWithin"
                    Value="False" />
                <Condition
                    Property="IsSelected"
                    Value="True" />
            </MultiTrigger.Conditions>
            <Setter
                Property="Background"
                Value="{DynamicResource
                    {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}" />
            <Setter
                Property="Foreground"
                Value="{DynamicResource
                    {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}" />
        </MultiTrigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition
                    Property="IsKeyboardFocusWithin"
                    Value="True" />
                <Condition
                    Property="IsSelected"
                    Value="True" />
            </MultiTrigger.Conditions>
            <Setter
                Property="Background"
                Value="{DynamicResource
                    {x:Static SystemColors.HighlightBrushKey}}" />
            <Setter
                Property="Foreground"
                Value="{DynamicResource
                    {x:Static SystemColors.HighlightTextBrushKey}}" />
        </MultiTrigger>
    </Style.Triggers>
</Style>

Обратите внимание, что есть ошибка: для установки контекстного меню строки необходимо переопределить стиль DataGridRow на DataGrid, поэтому, если вы делаете это глобально, и это не работает, проверьте, что RowStyle не было отменено.

...