C# DataGrid嵌套DataGrid动态隐藏显示行

前端代码:

<Window x:Class="DataGridPractice.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:DataGridPractice"      
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid Margin="0,0,0,214" Loaded="Grid_Loaded">

        <Grid.Resources>
            <DataTemplate x:Key="DataGridTemplateA">
                <DataGrid Name="DataGrid2" 
                          HeadersVisibility="None" 
                          CanUserAddRows="False" CanUserDeleteRows="False"
                          CanUserResizeColumns="False" CanUserResizeRows="False"
                          CanUserReorderColumns="False" CanUserSortColumns="False" 
                          AutoGenerateColumns="False" HorizontalAlignment="Left"
                          >
                    <DataGrid.Columns>
                        <DataGridTextColumn DisplayIndex="0" Binding="{Binding name, Mode=TwoWay}"/>
                    </DataGrid.Columns>
                </DataGrid>
            </DataTemplate>
        </Grid.Resources>

        <DataGrid Name="DataGrid1" 
                  CanUserAddRows="False" CanUserDeleteRows="False"
                  CanUserResizeColumns="False" CanUserResizeRows="False"
                  CanUserReorderColumns="False" CanUserSortColumns="False" 
                  AutoGenerateColumns="False"  HorizontalAlignment="Left"
                  VerticalContentAlignment="Center">

            <DataGrid.Columns>

                <DataGridTextColumn DisplayIndex="0" Binding="{Binding id, Mode=TwoWay}" />

                <DataGridTextColumn DisplayIndex="1" Binding="{Binding name, Mode=TwoWay}"/>

                <DataGridTextColumn DisplayIndex="2" Binding="{Binding age, Mode=TwoWay}"/>

                <DataGridTextColumn DisplayIndex="3" Binding="{Binding TotalCount, Mode=TwoWay}"/>

                <DataGridTemplateColumn DisplayIndex="4" CellTemplate="{StaticResource DataGridTemplateA}" IsReadOnly="True" Header="2"/>

            </DataGrid.Columns>
        </DataGrid>
        <TextBox HorizontalAlignment="Left" Height="38" Margin="117,310,0,-143" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="154" LostFocus="TextBox_LostFocus"/>
    </Grid>
</Window>

 

后端代码:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace DataGridPractice
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            LoadData();     
        }
        public List<Person> list { get; set; }

        public List<Character> characterlist { get; set; }
        public void LoadData()
        {
            Random r = new Random();
            list = new List<Person>();

            //Person person = new Person();
            //person.id = 1;
            //person.name = "张三1";
            //person.age = r.Next(100);
            //person.TotalCount = 5;
            //list.Add(person);


            characterlist = new List<Character>();

            Character chara1 = new Character();
            chara1.name = "A";
            characterlist.Add(chara1);

            Character chara2 = new Character();
            chara2.name = "B";
            characterlist.Add(chara2);

            Character chara3 = new Character();
            chara3.name = "C";
            characterlist.Add(chara3);


            for (int i = 0; i < 9; i++)
            {

                if (i > 1)
                    break;

                Person person = new Person();
                person.id = i + 1;
                person.name = "张三" + i;
                person.age = r.Next(100);
                person.TotalCount = 5;

                list.Add(person);
            }
        }

        private void Grid_Loaded(object sender, RoutedEventArgs e)
        {
            DataGrid1.ItemsSource = list;

            DataGridTemplateColumn templeColumn = DataGrid1.Columns[4] as DataGridTemplateColumn;
            if (templeColumn == null) return;

            for (int i = 0; i < DataGrid1.Items.Count; i++)
            {
                DataGridCell dataGridCell = GetDataGridCell(i, 0);
                if (dataGridCell != null)
                {
                    DataGridCellInfo dataGridCellInfo = new DataGridCellInfo(dataGridCell);

                    if (dataGridCellInfo.Item != null)
                    {
                        object item = dataGridCellInfo.Item;

                        FrameworkElement element = templeColumn.GetCellContent(item);

                        if (element != null)
                        {
                            DataGrid dataGrid2 = (DataGrid)templeColumn.CellTemplate.FindName("DataGrid2", element);
                            dataGrid2.ItemsSource = characterlist;                      
                        }
                    }
                }
            }
        }


        public DataGridCell GetDataGridCell(int rowIndex, int columnIndex)
        {
            try
            {
                DataGridRow rowContainer = GetDataGridRow(rowIndex);
                if (rowContainer != null)
                {
                    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
                    //这行代码是通过行得到单元格

                    DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
                    //这行代码是通过index得到具体的单元格

                    if (cell == null)
                    {
                        DataGrid1.ScrollIntoView(rowContainer, DataGrid1.Columns[columnIndex]);
                        cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
                    }
                    return cell;
                }
            }
            catch
            {
                return null;
            }
            return new DataGridCell();
        }

        public DataGridRow GetDataGridRow(int index)
        {
            if (index >= DataGrid1.Items.Count)
            {
                throw new IndexOutOfRangeException(String.Format("Index {0} is out of range.", index));
            }

            DataGridRow row = (DataGridRow)DataGrid1.ItemContainerGenerator.ContainerFromIndex(index);
            if (row == null)
            {
                // may be virtualized, bring into view and try again
                DataGrid1.ScrollIntoView(DataGrid1.Items[index]);
                WaitFor(TimeSpan.Zero, DispatcherPriority.SystemIdle);
                row = (DataGridRow)DataGrid1.ItemContainerGenerator.ContainerFromIndex(index);
            }

            return row;
        }
        public void WaitFor(TimeSpan time, DispatcherPriority priority)
        {
            DispatcherTimer timer = new DispatcherTimer(priority);
            timer.Tick += new EventHandler(OnDispatched);
            timer.Interval = time;
            DispatcherFrame dispatcherFrame = new DispatcherFrame(false);
            timer.Tag = dispatcherFrame;
            timer.Start();
            Dispatcher.PushFrame(dispatcherFrame);
        }
        public void OnDispatched(object sender, EventArgs args)
        {
            DispatcherTimer timer = (DispatcherTimer)sender;
            timer.Tick -= new EventHandler(OnDispatched);
            timer.Stop();
            DispatcherFrame frame = (DispatcherFrame)timer.Tag;
            frame.Continue = false;
        }

        public T GetVisualChild<T>(Visual parent) where T : Visual
        {
            T childContent = default(T);
            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                childContent = v as T;
                if (childContent == null)
                {
                    childContent = GetVisualChild<T>(v);
                }
                if (childContent != null)
                {
                    break;
                }
            }
            return childContent;
        }

        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            DataGridTemplateColumn templeColumn = DataGrid1.Columns[4] as DataGridTemplateColumn;
            if (templeColumn == null) return;

            for (int i = 0; i < DataGrid1.Items.Count; i++)
            {
                DataGridCell dataGridCell = GetDataGridCell(i, 0);
                if (dataGridCell != null)
                {
                    DataGridCellInfo dataGridCellInfo = new DataGridCellInfo(dataGridCell);

                    if (dataGridCellInfo.Item != null)
                    {
                        object item = dataGridCellInfo.Item;

                        FrameworkElement element = templeColumn.GetCellContent(item);

                        if (element != null)
                        {
                            DataGrid dataGrid2 = (DataGrid)templeColumn.CellTemplate.FindName("DataGrid2", element);
                            dataGrid2.ItemsSource = characterlist;

                            DataGridRow row = (DataGridRow)dataGrid2.ItemContainerGenerator.ContainerFromIndex(2);
                            row.Visibility = Visibility.Collapsed;
                        }
                    }
                }
            } 
        }
    }



    public class Person
    {
        public int id { get; set; }
        public string name { get; set; }
        public int age { get; set; }

        public int TotalCount { get; set; }
    }



    public class Character
    {
        public string name { get; set; }
    }
}

 

效果图:

 

 点击TextBox后再点击DataGrid效果图:

 

posted on 2022-12-05 11:50  wu.g.q  阅读(127)  评论(0编辑  收藏  举报

导航