2012-03-19 2 views
1

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

Для этого я в основном размещаю второй datagrid внутри родительских сеток RowDetailsTemplate и триггер стиля, чтобы перевернуть свойство detailvisibility в каждой строке. например

<Grid> 
    <DataGrid AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="source" Margin="10,10,14,14" Name="dataGrid1" RowDetailsVisibilityMode="Collapsed" SelectionMode="Single"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Binding="{Binding FullName}" Header="Name" /> 
      <DataGridTextColumn Binding="{Binding Details}" Header="Details" /> 
     </DataGrid.Columns> 
     <DataGrid.RowDetailsTemplate> 
      <DataTemplate> 
       <DataGrid HeadersVisibility="None" AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="{Binding Path=Attachments}"> 
        <DataGrid.Columns> 
         <DataGridTextColumn Binding="{Binding Document}" Header="Document" /> 
         <DataGridTextColumn Binding="{Binding Created}" Header="Date Created" /> 
        </DataGrid.Columns> 
       </DataGrid> 
      </DataTemplate> 
     </DataGrid.RowDetailsTemplate> 
     <DataGrid.RowHeaderTemplate> 
      <DataTemplate> 
       <ToggleButton IsChecked="{Binding Converter={StaticResource visibleConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=DetailsVisibility}"> 
        <Image> 
         <Image.Style> 
          <Style TargetType="Image"> 
           <Style.Triggers> 
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton}, Path=IsChecked}" Value="false"> 
             <Setter Property="Image.Source" Value="Images/plus-8.png" /> 
            </DataTrigger> 
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton}, Path=IsChecked}" Value="true"> 
             <Setter Property="Image.Source" Value="Images/minus-8.png" /> 
            </DataTrigger> 
           </Style.Triggers> 
          </Style> 
         </Image.Style> 
        </Image> 
       </ToggleButton> 
      </DataTemplate> 
     </DataGrid.RowHeaderTemplate> 
    </DataGrid> 
</Grid> 

Проблема 1, когда я использовать клавиатуру для перемещения вверх и вниз по родительской сетке он пропускает ребенок сетку, пропуская область RowDetailsTemplate.

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

Может ли кто-нибудь дать мне какие-либо указания относительно того, как обойти эти проблемы?

Здесь код для видимостиКонвертер, упомянутый в XAML выше;

public class VisibleConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     bool visibleValue = false; 
     if (value != null && value is Visibility) 
     { 
      visibleValue = !((Visibility)value == Visibility.Collapsed); 
     } 
     return visibleValue; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     Visibility visibleValue = Visibility.Collapsed; 
     if (value is bool) 
     { 
      if ((bool)value == true) 
      { 
       visibleValue = Visibility.Visible; 
      } 
     } 
     return visibleValue; 
    } 
} 
+0

побочный эффект: взломайте события SelectedGell DataCridChanged и/или SelectionChanged; при запуске используйте EventArgs, чтобы отменить выбор предыдущих дочерних ячеек. –

+0

Я изо всех сил пытаюсь понять, как получить ранее выбранные дочерние клетки, какие-либо подсказки? Я довольно новичок в WPF благодаря –

+0

ну, когда выбраны какие-либо ячейки, события должны быть подняты; поэтому, только ячейки в локальной переменной (например, List selectedCells;); тогда, когда события будут подняты, проверьте локальную переменную, чтобы увидеть, есть ли какие-либо ячейки и отменить выбор; затем сохраните вновь выбранные ячейки в локальной переменной. –

ответ

0

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

private void Expander_Expanded(object sender, RoutedEventArgs e) 
{ 
    foreach (var item in viewModel.Results) 
    { 
    if (item.SubResults.Count > 0) 
     { 
     item.SubResults.SelectedItem = null; 
     } 
    } 
} 

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

Смежные вопросы