Развернуть / свернуть строку по клику, вложенная сетка данных - PullRequest
0 голосов
/ 04 июля 2019

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

Я пытался захватить событие PreviewMouseLeftButtonDown для DataGridRow, но событие срабатывает для каждой вложенной сетки данных, когда они раскрываются (т. Е. Если я нажимаю на третьем уровне, событие запускается трижды), и я не могу различать их (IsMouseOver и т. д. верно для всех отправителей событий).

Есть ли способ заставить событие срабатывать только для затронутой строки? Или какой-то более простой способ сделать это?

XAML:

<Window x:Class="StackOverflowEx.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StackOverflowEx"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid Height="450">
        <DataGrid CanUserAddRows="False" AutoGenerateColumns="False" x:Name="MainGrid" FontWeight="Bold" RowHeight="60" ItemsSource="{Binding FirstLevel}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Test" Binding="{Binding Name, FallbackValue='Test'}" />
            </DataGrid.Columns>
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridRow_PreviewMouseLeftButtonDown"/>
                </Style>
            </DataGrid.RowStyle>
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <DataGrid CanUserAddRows="False" AutoGenerateColumns="False" Margin="60, 0, 0, 0" FontWeight="Regular" RowHeight="30" HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding NextLevel}">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Test" Binding="{Binding Name, FallbackValue='Test'}" />
                        </DataGrid.Columns>
                        <DataGrid.RowStyle>
                            <Style TargetType="{x:Type DataGridRow}">
                                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridRow_PreviewMouseLeftButtonDown" />
                            </Style>
                        </DataGrid.RowStyle>
                        <DataGrid.RowDetailsTemplate>
                            <DataTemplate>
                                <DataGrid CanUserAddRows="False" AutoGenerateColumns="False"  Margin="60, 0, 0, 0" FontWeight="Regular" RowHeight="30" HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding NextLevel}">
                                    <DataGrid.Columns>
                                        <DataGridTextColumn Header="Test" Binding="{Binding Name, FallbackValue='Test'}" />
                                    </DataGrid.Columns>
                                    <DataGrid.RowStyle>
                                        <Style TargetType="{x:Type DataGridRow}">
                                            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridRow_PreviewMouseLeftButtonDown" />
                                        </Style>
                                    </DataGrid.RowStyle>
                                    <DataGrid.RowDetailsTemplate>
                                        <DataTemplate>
                                            <DataGrid CanUserAddRows="False" AutoGenerateColumns="False" Margin="40, 0, 0, 0" RowHeight="20" FontWeight="Regular" HorizontalScrollBarVisibility="Disabled" ColumnWidth="60" ItemsSource="{Binding NextLevel}">
                                                <DataGrid.Columns>
                                                    <DataGridTextColumn Header="Test" Binding="{Binding Name, FallbackValue='Test'}" />
                                                </DataGrid.Columns>
                                            </DataGrid>
                                        </DataTemplate>
                                    </DataGrid.RowDetailsTemplate>
                                </DataGrid>
                            </DataTemplate>
                        </DataGrid.RowDetailsTemplate>
                    </DataGrid>
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>
    </Grid>
</Window>

Код сзади:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private ObservableCollection<DataClass> firstLevel = new ObservableCollection<DataClass>();
    private ObservableCollection<DataClass> secondLevel = new ObservableCollection<DataClass>();
    private ObservableCollection<DataClass> thirdLevel = new ObservableCollection<DataClass>();
    private ObservableCollection<DataClass> fourthLevel = new ObservableCollection<DataClass>();

    public ObservableCollection<DataClass> FirstLevel
    {
        get => firstLevel; set
        {
            firstLevel = value;
            NotifyPropertyChanged();
        }
    }
    public ObservableCollection<DataClass> SecondLevel
    {
        get => secondLevel; set
        {
            secondLevel = value;
            NotifyPropertyChanged();
        }
    }
    public ObservableCollection<DataClass> ThirdLevel
    {
        get => thirdLevel; set
        {
            thirdLevel = value;
            NotifyPropertyChanged();
        }
    }
    public ObservableCollection<DataClass> FourthLevel
    {
        get => fourthLevel; set
        {
            fourthLevel = value;
            NotifyPropertyChanged();
        }
    }

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;

        FourthLevel.Add(new DataClass { Name = "Fourth" });

        ThirdLevel.Add(new DataClass { Name = "Third" });
        ThirdLevel.Last().NextLevel = FourthLevel;

        SecondLevel.Add(new DataClass { Name = "Second" });
        SecondLevel.Last().NextLevel = ThirdLevel;

        FirstLevel.Add(new DataClass { Name = "First" });
        FirstLevel.Last().NextLevel = SecondLevel;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void DataGridRow_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DataGridRow row = sender as DataGridRow;
        if (row != null)
        {
            row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
        }
    }
}

public class DataClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public string Name { get; set; }
    public ObservableCollection<DataClass> NextLevel { get; set; } = new ObservableCollection<DataClass>();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...