簡體   English   中英

WPF:通過高度網格快速自動調整大小

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM