Невозможно выбрать несколько строк в сетке данных WPF

#c# #wpf #datagrid #selecteditem

#c# #wpf #datagrid #selecteditem

Вопрос:

Несмотря на то, что я получил SelectionMode="Extended" и SelectionUnit="FullRow" установил, когда я отлаживаю SelectionChanged событие, всегда есть только один выбранный элемент SelectedItems .

Это мой DataGrid :

 <DataGrid Grid.Row="0" AutoGenerateColumns="False" Margin="5,5,5,0"
        Name="dgrMembersClub1" ItemsSource="{Binding .}" CanUserAddRows="False"
        SelectionMode="Extended" SelectionUnit="FullRow" SelectionChanged="Grid_SelectionChanged">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Joining" >
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding IsSelected}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn IsReadOnly="True" Header="Surname" Binding="{Binding Surname}" />
        <DataGridTextColumn IsReadOnly="True" Header="Name" Binding="{Binding Name}" />
        <DataGridTextColumn IsReadOnly="True" Header="Club" Binding="{Binding Club_Id, Converter={StaticResource ClubName}}" />
        <DataGridTextColumn IsReadOnly="True" Header="City" Binding="{Binding City}" />
    </DataGrid.Columns>
</DataGrid>
  

И мое Grid_SelectionChanged событие:

 private void Grid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    DataGrid grid = (DataGrid)sender;
    var test = grid.SelectedItems; //Count == 1 (always)
}
  

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

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

Пока вы этим занимаетесь, я мог бы воспользоваться некоторой помощью, чтобы флажок в шаблоне ячейки тоже работал. Довольно, пожалуйста 🙂

Комментарии:

1. Вы можете привязаться к SelectedItems.

2. @GayotFow: это приведет к удалению всех элементов, которые не выбраны в сетке данных, верно? На самом деле это не то, чего я хочу. Проблема в том, что я не могу выбрать более 1 строки.

3. Нет, из сетки ничего не удаляется. Это массив выбранных элементов. Я все время привязываюсь к нему.

Ответ №1:

Свойство SelectedItems сетки данных содержит список выбранных элементов…

 private void DataGrid_SelectionChanged(object sender,
    SelectionChangedEventArgs e)
{
    // ... Get SelectedItems from DataGrid.
    var grid = sender as DataGrid;
    var selected = grid.SelectedItems;

    foreach (var item in selected)
    {
        var dog = item as Dog;
    }
}
  

Этот показательный обработчик событий получает SelectedItems и перебирает его.

Однако есть предостережение:

«Если для свойства SelectionMode установлено значение Single, список SelectedItems будет содержать только значение свойства SelectedItem».

Источник: http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.selecteditems (v= против 95).aspx

Свойство SelectedItems наследуется от IList, поэтому его можно использовать и выполнять с ним операции LINQ. Он также отлично работает с несмежными выборками.

Дополнительные советы на http://www.dotnetperls.com/datagrid

Комментарии:

1. Спасибо, я знаком с идеей сеток данных и выбора элементов. Проблема в том, что я больше знаком с мобильными платформами, такими как Windows Phone и Windows RT, где для выбора нескольких элементов не требуется нажатие клавиши CTRL. Мне просто нужно определить коллекцию, в которую я могу добавлять / удалять элементы, на которые нажимают. Это обычно создает мерцание. Но все же, спасибо за ответ, это заставило меня задуматься 😉

2. Помощь уже в пути. Моя книга о рецептах сетки данных освещает множество различных шаблонов, которые можно использовать в качестве шаблонов.

Ответ №2:

 private IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
    var itemsSource = grid.ItemsSource as IEnumerable;
    if (null == itemsSource) yield return null;
    foreach (var item in itemsSource)
    {
        var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
        if (null != row amp; row.IsSelected) yield return row;
    }
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    var rows = GetDataGridRows(dgv_Students);
    string id; //Sample =>"85-999888-2"
    foreach (DataGridRow dr in rows)
    {
        id = (dr.Item as tbl_student).code_meli;
        MessageBox.Show(id);
    }
}
  

Комментарии:

1. Просто рекомендация: вы должны добавить некоторое объяснение высокого уровня в свой ответ.