2016-11-11 24 views
13

Tôi có một ứng dụng WPF cần phải đáp ứng. Những gì tôi muốn có là một DataGrid bên trong một Grid. Khi cửa sổ giảm xuống, tôi muốn Grid đổi kích thước trước và sau đó là DataGrid. Dưới đây là những gì tôi đạt được cho đến nay:Thay đổi thứ tự mở rộng WPF

enter image description here

Trong gif trên đầu bạn có thể thấy rằng Grid thay đổi kích thước đầu tiên, và khi nó đạt đến đó là kích thước rộng tối thiểu, nó đi qua đáy DataGrid. Không chính xác những gì tôi muốn bởi vì tôi muốn mở rộng bố cục trước, sau đó hiển thị thanh cuộn trong DataGrid thay vì bố cục vừa xem qua nó. Vì vậy, tôi thử như sau:

enter image description here

Ngay ở đây bạn có thể thấy rằng nó cho thấy thanh cuộn như tôi muốn. Điều duy nhất là nó đầu tiên thay đổi kích thước của DataGrid, và khi nó được thực hiện thay đổi kích thước của DataGrid, nó bắt đầu thay đổi kích thước Grid. Tôi muốn nó là một cách khác xung quanh, đầu tiên thay đổi kích thước lưới điện, sau đó thay đổi kích thước DataGrid và hiển thị thanh cuộn. Vì vậy, về cơ bản tôi đang tìm kiếm một giải pháp thực hiện những điều sau:

  1. Quy mô cửa sổ làm lưới.
  2. Quy mô lưới cho đến khi kích thước tối thiểu là
  3. Khi đã đạt đến kích thước tối thiểu và nó vẫn thu nhỏ hơn, hiển thị thanh cuộn trong DataGrid.

Vì vậy mà đi xuống đến các Gif đầu từ câu hỏi này, tiếp theo là thanh cuộn trong DataGrid

Có cách nào để làm điều này? Có vẻ như tôi rất gần vì đó là sự kết hợp của hai điều đó nhưng tôi không biết làm thế nào. Đây là mã của tôi:

<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> 
+0

Tôi nghĩ rằng 'RowDefinition'' Height' mặc định là 'Auto', do đó cả hai định nghĩa hàng của bạn' Heights' được đặt là 'Auto'. Hãy thử sử dụng 'Height =" * "' trên 'DataGridRow'' RowDefinition' của bạn. – Jose

+0

@Kirenenko nếu tôi đặt 'Height =" * "' và 'maxheight =" 240 "' trong RowDefinition của tôi, tôi nhận được kết quả tương tự như trong gif đầu tiên – Markinson

Trả lời

6

Trong những trường hợp giải phương trình bố trí không còn khả thi với các khối xây dựng mặc định, bạn có thể tự mình thực hiện các phép tính . Để một công cụ chuyển đổi tính toán khoảng trống có sẵn còn lại.

Vấn đề còn lại là hai khía cạnh:

  1. Các DataGrid chỉ có thể co lại khi các hàng có kích thước sao có ActualHeight 0.

    Giải pháp: DataGrid.Style mà bộ dataGrid.MaxHeight khi triggerGrid.ActualHeight = 0 (triggerGrid chiếm một ngôi sao có kích thước hàng).

  2. Khi chúng tôi đưa ra một MinHeight-DataGridRow nó sẽ không co lại khi các dataGrid.ActualHeight co lại (nó đánh cắp bị thu hẹp chiều cao sau).

    Giải pháp: RowDefinition.Style mà bộ MinHeight để dataGrid.ActualHeight khi triggerGrid.ActualHeight = 0 và đến giá trị cố định của nó bằng cách khác.

tôi đã thiết BackGround màu sắc phần Kiểm soát để minh họa khi chiều cao cỡ sao (còn lại khoảng trắng) trở thành 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> 

Converters

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(); 
    } 
} 
+0

Hoạt động hoàn hảo! Cảm ơn rất nhiều vì đã dành thời gian và giúp đỡ bạn. – Markinson

+0

@Derp Bạn được chào đón. – Funk

2

Đây không phải là câu trả lời chính xác. Nhưng, nó sẽ đưa ra một ý tưởng để đạt được nhu cầu của bạn.

<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> 

Hy vọng điều đó sẽ hữu ích.

Các vấn đề liên quan