[英]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.