【问题标题】:Change scaling order WPF更改缩放顺序 WPF
【发布时间】:2017-03-25 17:09:43
【问题描述】:

我有一个需要响应式的 WPF 应用程序。我想要的是在Grid 中的DataGrid。当窗口缩小时,我希望Grid 先调整大小,然后再调整DataGrid。以下是我目前取得的成就:

在顶部的 gif 中,您可以看到 Grid 首先调整大小,当它达到最小缩放大小时,它会越过底部 DataGrid。不完全是我想要的,因为我想先缩放布局,然后在 DataGrid 中显示一个滚动条,而不是仅仅覆盖它的布局。所以我尝试了以下方法:

在这里你可以看到它显示了我想要的滚动条。唯一的事情是它首先调整 DataGrid 的大小,当它调整完 DataGrid 的大小时,它开始调整 Grid 的大小。我希望它反过来,首先调整网格的大小,然后调整 DataGrid 的大小并显示滚动条。所以基本上我正在寻找一种解决方案,它可以执行以下操作:

  1. 缩放用于缩放网格的窗口。
  2. 将网格缩放到最小尺寸
  3. 当它达到最小尺寸并且仍然变小时,在 DataGrid 中显示滚动条。

所以这归结为这个问题的第一个 Gif,然后是 DataGrid 中的滚动条

有没有办法做到这一点?看起来我很接近,因为它是这两件事的结合,但我不知道如何。这是我的代码:

<Grid Grid.Row="1" HorizontalAlignment="Right"  Grid.Column="0">
  <Grid ShowGridLines="False">
    <Grid.RowDefinitions>
      <RowDefinition MaxHeight="50"/>
      <RowDefinition Height="auto"/>
      <RowDefinition MaxHeight="20"/>
      <RowDefinition Height="auto"/>
      <RowDefinition MaxHeight="5"/>
      <RowDefinition Height="auto"/>
      <RowDefinition MaxHeight="5"/>
      <RowDefinition Height="auto"/>
      <RowDefinition MaxHeight="5"/>
      <RowDefinition Height="auto"/>
      <RowDefinition MaxHeight="50"/>
      <RowDefinition Height="auto"/>
      <RowDefinition MaxHeight="50"/>
      <RowDefinition Height="auto"/>
      <RowDefinition MaxHeight="5"/>
      <RowDefinition Name="DataGridRow" Height="*" MaxHeight="240" />
    </Grid.RowDefinitions>

    <Label Grid.Row="1" FontSize="24">Test</Label>
    <Label Grid.Row="3" Content="Test"/>
    <ComboBox Grid.Row="5" MaxWidth="500" MinWidth="300" HorizontalAlignment="Left"  />
    <Label Grid.Row="7" Content="Test"/>
    <ComboBox Grid.Row="9" MaxWidth="500" MinWidth="300" HorizontalAlignment="Left"/>
    <Separator Grid.Row="11"/>

    <Label Grid.Row="13" Content="Test" />
    <Grid Grid.Row="15">
      <DataGrid
          RowHeight="40"
           CanUserAddRows="False"
            x:Name="dataGrid"
            AutoGenerateColumns="False"
            CanUserResizeColumns="True"
            HeadersVisibility="None"
            GridLinesVisibility="None"
            ScrollViewer.CanContentScroll="True"
            ScrollViewer.VerticalScrollBarVisibility="Visible"
            ScrollViewer.HorizontalScrollBarVisibility="Auto"
        <DataGrid.Columns>
          <DataGridTextColumn IsReadOnly="True" Width="*" Binding="{Binding Name}">
            <DataGridTextColumn.ElementStyle>
              <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center" />
                <Setter Property="Margin" Value="2,0,0,0"/>
              </Style>
            </DataGridTextColumn.ElementStyle>
          </DataGridTextColumn>
        </DataGrid.Columns>
      </DataGrid>
    </Grid>
  </Grid>
</Grid>

【问题讨论】:

  • 我认为RowDefinition Height 默认为Auto,因此您的两个行定义Heights 都设置为Auto。尝试在您的 DataGridRow RowDefinition 上使用 Height="*"
  • @Kirenenko 如果我在 RowDefinition 中设置 Height="*"maxheight="240",我会得到与第一个 gif 中相同的结果

标签: wpf xaml user-interface datagrid


【解决方案1】:

在使用默认构建块无法再求解布局方程的情况下,您可以 自己做计算。让转换器计算剩余的可用空间。

剩下的问题是双重的:

  1. DataGrid 可能仅在星号大小的行具有 ActualHeight0.

    解决方案:DataGrid.Style 设置 dataGrid.MaxHeighttriggerGrid.ActualHeight = 0 (triggerGrid 占星大小 行)。

  2. 当我们将 MinHeight 分配给 DataGridRow 时,它不会缩小 dataGrid.ActualHeight 缩小(它窃取了缩小的高度 返回)。

    解决方案:RowDefinition.Style 将其 MinHeight 设置为 dataGrid.ActualHeighttriggerGrid.ActualHeight = 0 时 否则为固定值。

我已经设置了控件的BackGround 颜色来说明星星大小的高度(剩余的空白区域)何时变为 0。

<Window 

    ...

    Width="200" Height="450">
    <Window.Resources>
        <local:HeightConverter x:Key="HeightConverter" />
        <local:IsEqualToZeroConverter x:Key="IsEqualToZeroConverter" />
    </Window.Resources>
    <!--MainGrid-->
    <Grid x:Name="mainGrid">
        <Grid ShowGridLines="False">
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="50"/>
                <RowDefinition Height="auto"/>
                <RowDefinition MaxHeight="20"/>
                <RowDefinition Height="auto"/>
                <RowDefinition MaxHeight="5"/>
                <RowDefinition Height="auto"/>
                <RowDefinition MaxHeight="5"/>
                <RowDefinition Height="auto"/>
                <RowDefinition MaxHeight="5"/>
                <RowDefinition Height="auto"/>
                <RowDefinition MaxHeight="50"/>
                <RowDefinition Height="auto"/>
                <RowDefinition MaxHeight="50"/>
                <RowDefinition Height="auto"/>
                <RowDefinition MaxHeight="5"/>
                <RowDefinition x:Name="dataGridRow" Height="Auto">
                    <RowDefinition.Style>
                        <Style TargetType="{x:Type RowDefinition}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding ActualHeight, ElementName=triggerGrid, Converter={StaticResource IsEqualToZeroConverter}}" Value="True">
                                    <Setter  Property="MinHeight" Value="{Binding ActualHeight, ElementName=dataGrid}"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ActualHeight, ElementName=triggerGrid, Converter={StaticResource IsEqualToZeroConverter}}" Value="False">
                                    <Setter  Property="MinHeight" Value="80.0"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </RowDefinition.Style>
                </RowDefinition>
            </Grid.RowDefinitions>
            <Label x:Name="bigLabel" Grid.Row="1" FontSize="24" Background="LightGray">Test</Label>
            <Label x:Name="regularLabel" Grid.Row="3" Content="Test" Background="LightGray"/>
            <ComboBox x:Name="comboBox" Grid.Row="5" MaxWidth="500" MinWidth="300" HorizontalAlignment="Left"  Background="LightGray" />
            <Label Grid.Row="7" Content="Test" Background="LightGray"/>
            <ComboBox Grid.Row="9" MaxWidth="500" MinWidth="300" HorizontalAlignment="Left" Background="LightGray"/>
            <Separator x:Name="separator" Grid.Row="11"/>
            <Label Grid.Row="13" Content="Test"  Background="LightGray"/>
            <!--TriggerGrid-->
            <Grid Grid.Row="14" x:Name="triggerGrid"/>
            <Grid Grid.Row="15">
                <DataGrid
                    x:Name="dataGrid"
                    RowHeight="40"
                    CanUserAddRows="False"
                    AutoGenerateColumns="False"
                    CanUserResizeColumns="True"
                    HeadersVisibility="None"
                    GridLinesVisibility="None"
                    ScrollViewer.CanContentScroll="True"
                    ScrollViewer.VerticalScrollBarVisibility="Visible"
                    ScrollViewer.HorizontalScrollBarVisibility="Auto">
                    <DataGrid.Style>
                        <Style TargetType="{x:Type DataGrid}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding ActualHeight, ElementName=triggerGrid}" Value="0">
                                    <Setter Property="MaxHeight">
                                        <Setter.Value>
                                            <MultiBinding Converter="{StaticResource HeightConverter}">
                                                <Binding ElementName="mainGrid" Path="ActualHeight"/>
                                                <Binding ElementName="bigLabel" Path="ActualHeight"/>
                                                <Binding ElementName="regularLabel" Path="ActualHeight"/>
                                                <Binding ElementName="comboBox" Path="ActualHeight"/>
                                                <Binding ElementName="separator" Path="ActualHeight"/>
                                            </MultiBinding>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </DataGrid.Style>
                    <DataGrid.Columns>
                        <DataGridTextColumn IsReadOnly="True" Width="*" Binding="{Binding Name}">
                            <DataGridTextColumn.ElementStyle>
                                <Style TargetType="TextBlock">
                                    <Setter Property="VerticalAlignment" Value="Center" />
                                    <Setter Property="Margin" Value="2,0,0,0"/>
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                    </DataGrid.Columns>
                </DataGrid>
            </Grid>
        </Grid>
    </Grid>
</Window>

转换器

public class HeightConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        // only 1 check at startup (Debugging)
        if ((double)values[1] == 0.0) return 0.0;

        double mainGridHeight       = (double)values[0];
        double bigLabelHeight       = (double)values[1];
        double regularLabelHeight   = (double)values[2];
        double comboBoxHeight       = (double)values[3];
        double separatorHeight      = (double)values[4];

        double dataGridHeight = mainGridHeight - bigLabelHeight - 2 * (regularLabelHeight + comboBoxHeight) - regularLabelHeight - separatorHeight;

        if (dataGridHeight > 0.0) return dataGridHeight; else return 0.0;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class IsEqualToZeroConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((double)value == 0.0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

【讨论】:

  • 完美运行!非常感谢您的时间和帮助。
【解决方案2】:

这不是确切的答案。但是,它会提供一个想法来满足您的需求。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />            
        <RowDefinition Height="5" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <DockPanel>                        
        <TextBlock DockPanel.Dock="Bottom" Grid.Row="1" FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" MaxHeight="240">DataGrid</TextBlock>
        <Separator DockPanel.Dock="Bottom"/>
        <TextBlock DockPanel.Dock="Bottom" FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">Top</TextBlock>
    </DockPanel>
    <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" />
    <TextBlock Grid.Row="2" FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">Bottom</TextBlock>
</Grid>

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 1970-01-01
    相关资源
    最近更新 更多