【问题标题】:WPF DataGrid Need Vertical Scrollbar in Grid RowWPF DataGrid 需要网格行中的垂直滚动条
【发布时间】:2017-11-09 05:30:03
【问题描述】:

我的客户开发了一个包含多个属性部分的属性编辑器,这些属性部分显示为 WPF 扩展器,其中包含数据网格。我们在 WPF Grid 中布置了所有内容,目前具有自动调整大小的行。

我们试图解决的问题是当屏幕高度发生变化时每个属性部分的大小成比例。打开扩展器时,它们应该占用一定比例的空间,垂直滚动条会在需要时自动启动。当它们关闭时,它们应该折叠并将剩余空间留给其余部分。

在现实生活中,我们有 4 个带有内容的扩展器。第一个是固定高度,其余三个是列表和数据网格,它们需要按比例调整大小,最后一个获得剩余空间的最大部分。请记住,用户可能会调整屏幕大小,或者用户可能会以不同的屏幕分辨率运行,因此我们需要它做出相应的反应。

我们已经尝试弄乱 DataGrid RowDefinition Height(固定、比例和自动)和 MaxHeight,以及每个数据网格的 MaxHeight,但我似乎找不到导致整个区域被消耗的组合需要。我们正在研究基于代码的解决方案,但我们很好奇其他人可能会提出什么建议。

这是一个简单的代码示例,它将为您提供我们所追求的布局。我们只需要它像上面描述的那样工作。

这是代码(这将是现实世界中的视图模型)

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        datagrid1.DataContext = GetCustomerVM();
        datagrid2.DataContext = GetCustomerVM();
        datagrid3.DataContext = GetCustomerVM();
    }

    private List<Customer> GetCustomerVM()
    {
        var CustomerList = new List<Customer>();
        CustomerList.Add(new Customer() { FirstName = "A" });
        CustomerList.Add(new Customer() { FirstName = "A" });
        CustomerList.Add(new Customer() { FirstName = "A" });
        CustomerList.Add(new Customer() { FirstName = "A" });
        CustomerList.Add(new Customer() { FirstName = "A" });
        CustomerList.Add(new Customer() { FirstName = "A" });
        CustomerList.Add(new Customer() { FirstName = "A" });
        CustomerList.Add(new Customer() { FirstName = "A" });

        return CustomerList;
    }
}

public class Customer
{
    public string FirstName { get; set; }
}

XAML

<Window x:Class="StackOverflow_SidePanelGridScrolling.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:StackOverflow_SidePanelGridScrolling"
        mc:Ignorable="d"
        Loaded="Window_Loaded"
        Title="MainWindow" Height="500" Width="300">

    <Window.Resources>

        <DataTemplate x:Key="ExpanderHeaderTemplate">
            <DockPanel Height="30">
                <TextBlock Margin="4,0,0,0"
                               VerticalAlignment="Center"
                               DockPanel.Dock="Left"
                               FontSize="16"
                               Text="{Binding}" />

            </DockPanel>
        </DataTemplate>

        <Style TargetType="Expander">
            <Setter Property="HeaderTemplate" 
                    Value="{StaticResource ExpanderHeaderTemplate}" />
        </Style>

    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Expander x:Name="expander1" Grid.Row="0" Header="Area 1">

            <DataGrid Name="datagrid1" 
                      ItemsSource="{Binding}" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="First Name" 
                                        Binding="{Binding FirstName}"
                                        Width="100*" />
                </DataGrid.Columns>
            </DataGrid>

        </Expander>

        <Expander x:Name="expander2" Grid.Row="1" Header="Area 2">

            <DataGrid Name="datagrid2" 
                      ItemsSource="{Binding}" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="First Name" 
                                        Binding="{Binding FirstName}"
                                        Width="100*" />
                </DataGrid.Columns>
            </DataGrid>

        </Expander>

        <Expander x:Name="expander3" Grid.Row="3" Header="Area 3">

            <DataGrid Name="datagrid2" 
                      ItemsSource="{Binding}" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="First Name" 
                                        Binding="{Binding FirstName}"
                                        Width="100*" />
                </DataGrid.Columns>
            </DataGrid>

        </Expander>

    </Grid>
</Window>

【问题讨论】:

    标签: wpf datagrid vertical-scrolling


    【解决方案1】:

    就我能够理解您的要求而言,我认为这可以满足您的需求:

    • 每个扩展器在未扩展时都会占用它所需的最小空间。
    • 展开时,顶行会根据其内容调整大小。
    • 第二、三和四行将剩余空间分开。展开时,它们会伸展。两个得到一份可用空间,三个得到两份,四得到三份。如果 2 和 3 开放,则 2 获得 4 股之一, 3 获得另外 3 股。

    这些共享由the * Height values 在触发器的设置器中分发。这是第四行的触发器:

    <DataTrigger
        Binding="{Binding Children[3].IsExpanded, RelativeSource={RelativeSource AncestorType=Grid}}"
        Value="True"
        >
        <Setter Property="Height" Value="3*" />
    </DataTrigger>
    

    在 XAML 中这样做的好处是它永远不会给您带来任何丑陋的惊喜。

    这是 XAML:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition>
                <RowDefinition.Style>
                    <Style TargetType="RowDefinition">
                        <Setter Property="Height" Value="Auto" />
                        <Style.Triggers>
                            <DataTrigger
                                Binding="{Binding Children[1].IsExpanded, RelativeSource={RelativeSource AncestorType=Grid}}"
                                Value="True"
                                >
                                <Setter Property="Height" Value="1*" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </RowDefinition.Style>
            </RowDefinition>
            <RowDefinition>
                <RowDefinition.Style>
                    <Style TargetType="RowDefinition">
                        <Setter Property="Height" Value="Auto" />
                        <Style.Triggers>
                            <DataTrigger
                                Binding="{Binding Children[2].IsExpanded, RelativeSource={RelativeSource AncestorType=Grid}}"
                                Value="True"
                                >
                                <Setter Property="Height" Value="2*" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </RowDefinition.Style>
            </RowDefinition>
            <RowDefinition>
                <RowDefinition.Style>
                    <Style TargetType="RowDefinition">
                        <Setter Property="Height" Value="Auto" />
                        <Style.Triggers>
                            <DataTrigger
                                Binding="{Binding Children[3].IsExpanded, RelativeSource={RelativeSource AncestorType=Grid}}"
                                Value="True"
                                >
                                <Setter Property="Height" Value="3*" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </RowDefinition.Style>
            </RowDefinition>
        </Grid.RowDefinitions>
        <Expander
            Grid.Row="0"
            VerticalAlignment="Stretch"
            Header="One" Background="LightGreen">
            <StackPanel>
                <Label>Content One</Label>
                <Label>Content One</Label>
                <Label>Content One</Label>
            </StackPanel>
        </Expander>
        <Expander
            Grid.Row="1"
            VerticalAlignment="Stretch"
            Header="Two" Background="LightSkyBlue">
            <StackPanel>
                <Label>Content Two</Label>
                <Label>Content Two</Label>
                <Label>Content Two</Label>
            </StackPanel>
        </Expander>
        <Expander
            Grid.Row="2"
            VerticalAlignment="Stretch"
            Header="Three" Background="LightGoldenrodYellow">
            <StackPanel>
                <Label>Content Three</Label>
                <Label>Content Three</Label>
                <Label>Content Three</Label>
            </StackPanel>
        </Expander>
        <Expander
            Grid.Row="3"
            VerticalAlignment="Stretch"
            Header="Four" Background="Khaki">
            <StackPanel>
                <Label>Content Four</Label>
                <Label>Content Four</Label>
                <Label>Content Four</Label>
            </StackPanel>
        </Expander>
    </Grid>
    

    这些不显示滚动条,因为我没有花时间创建可滚动的内容。

    【讨论】:

    • Ed,这看起来像是解决方案。我不得不用多重触发器替换您的触发器,因为我忽略了最后一部分可以通过用户在此控件之外的屏幕另一个区域中的操作将可见性设置为折叠。所以在我们的版本中,grid 3 的触发器同时查看了 Grid 4 的 IsExpanded 和 Visibility 属性。谢谢您的帮助。如果我们有问题,我会报告。
    • @KyleLib 太棒了。祝你好运。
    猜你喜欢
    • 2012-12-05
    • 1970-01-01
    • 2018-12-16
    • 2019-07-20
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    相关资源
    最近更新 更多