我正在 DataRowTemplate 中寻找无限嵌套的 DataGrid。因此,当单击行时,我想显示另一个 DataGrid 等。我的主类是“CustomTable”,它继承自 BaseViewModel,该类提供 PropertyChanged 事件来更新视图。
这是我的.cs:
public class CustomTable : BaseViewModel
{
private ObservableCollection<DataTable> _main;
public ObservableCollection<DataTable> Main
{
get
{
return _main;
}
set
{
_main = value;
RaisePropertyChanged();
}
}
private CustomTable _child;
public CustomTable Child
{
get
{
return _child;
}
set
{
_child = value;
RaisePropertyChanged();
}
}
private DataRowView _selectedItem;
public DataRowView SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
Child = new CustomTable();
RaisePropertyChanged();
}
}
private ContentControl _tableCollection;
public ContentControl TableCollection
{
get
{
return _tableCollection;
}
set
{
_tableCollection = value;
RaisePropertyChanged();
}
}
public CustomTable()
{
Main = new ObservableCollection<DataTable>();
Main.Add(someRandomTable());
TableCollection = new ContentControl();
TableCollection.Content = Main;
}
private DataTable someRandomTable()
{
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add(25, "Indocin", "David", DateTime.Now);
table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
table.Rows.Add(53, "ACC", "Foobar", DateTime.Now);
return table;
}
}
这是我的 xaml:
<Window.DataContext>
<local:CustomTable/>
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="Nested">
<ItemsControl ItemsSource="{Binding DataContext.Tables, RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataGrid CanUserAddRows="False" RowDetailsTemplate="{DynamicResource Nested}" ItemsSource="{Binding Main}" AutoGenerateColumns="True" >
</DataGrid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<ScrollViewer>
<ScrollViewer.Resources>
<DataTemplate DataType="{x:Type local:CustomTable}">
<StackPanel>
<ItemsControl ItemsSource="{Binding Path=Main}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataGrid SelectedItem="{Binding SelectedItem, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor,AncestorType=ItemsControl}}"
CanUserAddRows="False" ItemsSource="{Binding}" AutoGenerateColumns="True" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Expander Header="Child" Margin="10" IsExpanded="True" x:Name="child">
<ContentControl Content="{Binding Child}"/>
</Expander>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Child}" Value="{x:Null}">
<Setter TargetName="child" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ScrollViewer.Resources>
<ContentControl Content="{Binding TableCollection}"/>
</ScrollViewer>
我从无限嵌套的DataGrid数据模板中得到了一些灵感,但这并没有真正的帮助。我还不能发表评论,被迫在这里寻求帮助。
我真的不明白问题出在哪里。感谢您的帮助!!!
为了获得准确的答案,需要一个最小的可重复示例。如果您可以将其发布到 GitHub 上并提供指向它的链接,那将会非常有帮助。这将使我们不再局限于一般性的言语和建议,而是向您展示解决方案。
我将根据对您发布的代码片段的分析得出的假设来写下我的建议和评论。
ObservableCollection<DataTable> Main
的 CustomTable
属性中的表集合。
至少,您需要从 ContentControl TableCollection
中删除 CustomTable
属性。这是一个 Visual 类,不应位于 ViewModel 中。此外,绑定到 ContentControl.Conten
属性的视觉类会导致数据模板被忽略。此行为内置于 ContentControl
逻辑中。 public class CustomTable : BaseViewModel
{
//private ObservableCollection<DataTable> _main;
public ObservableCollection<DataTable> Main { get; }
//{
// get
// {
// return _main;
// }
// set
// {
// _main = value;
// RaisePropertyChanged();
// }
//}
private CustomTable? _child;
public CustomTable? Child
{
get
{
return _child;
}
set
{
_child = value;
RaisePropertyChanged();
}
}
private DataRowView? _selectedItem;
public DataRowView? SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
Child ??= new CustomTable();
RaisePropertyChanged();
}
}
//private ContentControl? _tableCollection;
//public ContentControl? TableCollection
//{
// get
// {
// return _tableCollection;
// }
// set
// {
// _tableCollection = value;
// RaisePropertyChanged();
// }
//}
public CustomTable()
{
Main = new ObservableCollection<DataTable>
{
someRandomTable()
};
//TableCollection = new ContentControl();
//TableCollection.Content = Main;
}
private DataTable someRandomTable()
{
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add(25, "Indocin", "David", DateTime.Now);
table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
table.Rows.Add(53, "ACC", "Foobar", DateTime.Now);
return table;
}
}
</ScrollViewer.Resources>
<ContentControl Content="{Binding}"/>
</ScrollViewer>
public CustomTable()
{
Main = new ObservableCollection<DataTable>
{
someRandomTable(),
someRandomTable()
};
}
CustomTable.SelectedItem
属性的含义。根据 XAML,Main
属性的表之一中的一行绑定到此属性。但是这样的表有很多,但是绑定的属性只有一个。如果所选行位于多个表中,您期望什么行为?在大多数实现中,集合的属性和其中选择的元素是同一级别的属性。因此,如果没有您的额外澄清,我将无法给出适合您的准确答案。
using System;
using System.Collections.ObjectModel;
using System.Data;
namespace Core2023.SO.niconice.InfiniteDataGrid
{
public class CustomTable : BaseViewModel
{
public ObservableCollection<DataTable> Main { get; }
private CustomTable? _child;
public CustomTable? Child
{
get
{
return _child;
}
set
{
_child = value;
RaisePropertyChanged();
}
}
private DataRowView? _selectedItem;
public DataRowView? SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
Child ??= new CustomTable();
RaisePropertyChanged();
}
}
public CustomTable()
{
Main = new ObservableCollection<DataTable>
{
someRandomTable(),
someRandomTable()
};
}
private static DataTable someRandomTable()
{
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
table.Rows.Add(25, "Indocin", "David", DateTime.Now);
table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
table.Rows.Add(53, "ACC", "Foobar", DateTime.Now);
return table;
}
}
}
<Window x:Class="Core2023.SO.niconice.InfiniteDataGrid.InfiniteDataGridWindow"
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:Core2023.SO.niconice.InfiniteDataGrid"
mc:Ignorable="d"
Title="InfiniteDataGridWindow" Height="1000" Width="400">
<Window.DataContext>
<local:CustomTable/>
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="Nested">
<ItemsControl ItemsSource="{Binding DataContext.Tables, RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataGrid CanUserAddRows="False" RowDetailsTemplate="{DynamicResource Nested}" ItemsSource="{Binding Main}" AutoGenerateColumns="True" >
</DataGrid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<ScrollViewer>
<ScrollViewer.Resources>
<DataTemplate DataType="{x:Type local:CustomTable}">
<StackPanel>
<ItemsControl x:Name="Main_ItemsControl" ItemsSource="{Binding Path=Main}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataGrid SelectedItem="{Binding DataContext.SelectedItem, Mode=TwoWay, ElementName=Main_ItemsControl}"
CanUserAddRows="False" ItemsSource="{Binding}" AutoGenerateColumns="True" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Expander Header="Child" Margin="10" IsExpanded="True" x:Name="child">
<ContentControl Content="{Binding Child}"/>
</Expander>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Child}" Value="{x:Null}">
<Setter TargetName="child" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ScrollViewer.Resources>
<ContentControl Content="{Binding}"/>
</ScrollViewer>
</Window>