更改缩放顺序WPF

时间:2016-11-11 12:56:21

标签: wpf xaml user-interface datagrid

我有一个需要响应的WPF应用程序。我想要的是DataGrid内的Grid。当窗口缩小时,我希望Grid先调整大小,然后调整DataGrid。这是我到目前为止所取得的成就:

enter image description here

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

enter image description here

就在这里你可以看到它显示了我想要的滚动条。唯一的事情是它首先调整DataGrid的大小,当它完成DataGrid的大小调整后,它开始调整Grid的大小。我希望它是另一种方式,首先调整网格大小,然后调整DataGrid的大小并显示Scrollbars。所以基本上我正在寻找能够做到以下几点的解决方案:

  1. 缩放网格,缩放网格。
  2. 将网格缩放到最小尺寸
  3. 当它达到最小尺寸并且它仍然变小时,在DataGrid中显示滚动条。
  4. 所以这个问题归结为第一个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>
    

2 个答案:

答案 0 :(得分:6)

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

剩下的问题有两个:

  1. DataGrid只有在星大小的行有时才会收缩 ActualHeight 0。

    解决方案:DataGrid.Style设置dataGrid.MaxHeight的时间 triggerGrid.ActualHeight = 0(triggerGrid占据星号 行)。

  2. 当我们向MinHeight提供DataGridRow时,它不会缩小 dataGrid.ActualHeight收缩(它偷走了收缩的高度 回)。

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

  3. 我设置了控件'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();
        }
    }
    

答案 1 :(得分: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>

希望有所帮助。