[英]WPF: Fast auto-sizing by height grid
我必须将包含多个表的窗口实现到一个滚动查看器中。 这意味着该表应被内容拉伸。 用户能够向这些表添加/删除项目(行)。
以下模型显示了该概念。 主要问题是网格不应具有滚动条,而应具有动态高度。
目前,此接口已在ScrollViewer内部实现为ItemsControl。 在ItemsControl的ItemTemplate中添加了DataGrid来表示表格数据。
<ScrollViewer CanContentScroll="True"
HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Path=Groups}"
VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0"
Style="{StaticResource ResourceKey=LabelBaseStyle}"
Content="{Binding Path=GroupLabel}"
HorizontalAlignment="Right"/>
<Button Content="{x:Static Member=Resources:CommonStrings.Delete}"
Style="{StaticResource ResourceKey=ButtonBaseStyle}"
VerticalAlignment="Center" />
<DataGrid Grid.Row="0" Grid.Column="1"
AutoGenerateColumns="False"
ItemsSource="{Binding Path=Items}">
<DataGrid.Columns>
<!-- 21 text columns here -->
</DataGrid.Columns>
</DataGrid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
在添加一些数据之前,此解决方案可以正常工作。 现在,在7个表(网格)中每个表上大约有50个项目,应用程序不可能变得很慢:渲染它需要几分钟。 分析后,我发现几乎所有时间都花在Measure和Arrange方法上。 我还发现,建议不要将DataGrid用作约束对象,以无限的方式对其进行度量。 因此我无法理解问题,但是无法更改界面。
我尝试编写不带DataGrid的相同接口:用TextBlocks将其替换为ItemsControl。 此解决方案工作正常。 但是我有几个相似的接口,编写这么多相似的代码看起来不太好。 下面显示的代码替代了先前示例中的DataGrid:
<ItemsControl ItemsSource="{Binding Path=Items}"
VirtualizingStackPanel.IsVirtualizing="True"
Grid.Row="0" Grid.Column="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Type}" />
<!-- Another 20 TextBlocks here -->
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
因此,我需要实现自己的UserControl或找到一个可以使用的控件。 有人可以建议我吗? 也许一些解决方法或轻量级控制?
重新回答我。...这是您问题的更好解决方案。 我确定您可以弄清楚如何对其进行修改以使其起作用:
在我的主窗口Xaml中:
<ScrollViewer Height="Auto" Width="Auto" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Visible">
<StackPanel Height="Auto" Width="Auto">
<ItemsControl ItemsSource="{Binding ItemList}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type wpfmvvmtest:itemTypeA}">
<wpfmvvmtest:testUC></wpfmvvmtest:testUC>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</StackPanel>
</ScrollViewer>
例如,以下是主窗口(testVM)的主ViewModel,这些视图都是在构造函数中完成的:
public testVM()
{
ItemList = new ObservableCollection<object>();
Random rnd = new Random();
for (int i = 0; i < 3; i++)
{
itemTypeA item = new itemTypeA(rnd.Next(100));
ItemList.Add(item);
}
}
public ObservableCollection<object> ItemList { set; get; }
这就是“ itemTypeA”的样子:
public itemTypeA(int count)
{
Items = new DataTable();
Items.Columns.Add("One");
Items.Columns.Add("Two");
Items.Columns.Add("Three");
Items.Columns.Add("Four");
Description = "Count = " + count;
for (int i = 0; i < count; i++)
{
DataRow dr = Items.NewRow();
dr[0] = i*1;
dr[1] = i * 2;
dr[2] = i * 3;
dr[3] = i * 4;
Items.Rows.Add(dr);
}
}
public DataTable Items { set; get; }
这是重要的部分(请确保您在UserControl中没有为DataTemplate设置高度/宽度属性(这允许DataGrid设置高度/宽度):
<UserControl x:Class="wpfmvvmtest.testUC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DataContext="d:designInstance itemTypeA"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" HorizontalAlignment="Stretch" Content="{Binding Description}"></Label>
<Border Grid.Row="1" BorderBrush="Black" BorderThickness="2">
<DataGrid ItemsSource="{Binding Path=Items}">
</DataGrid>
</Border>
</Grid>
</UserControl>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.