바인딩 - wpf datagrid 예제




스케일링 순서 변경 WPF (2)

일종의 응답 성이 필요한 WPF 응용 프로그램이 있습니다. 내가 갖고 싶은 것은 Grid 내부의 DataGrid 입니다. 창 크기가 축소되면 Grid 크기를 먼저 조정 한 다음 DataGrid 크기를 조정합니다. 내가 지금까지 성취 한 것은 다음과 같습니다.

맨 위에있는 gif에서 Grid 먼저 크기 조정되고, 크기가 최소 크기에 도달하면 GridDataGrid 넘는 것을 볼 수 있습니다. 레이아웃을 먼저 크기 조절 한 다음 레이아웃 대신 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>

기본 방정식 블록을 사용하여 레이아웃 방정식을 더 이상 해결할 수없는 경우 직접 계산을 수행 할 수 있습니다. 변환기가 남은 사용 가능한 공간을 계산하도록합니다.

나머지 문제는 두 가지입니다.

  1. 별 크기의 행에 ActualHeight 0이있는 경우에만 DataGrid 가 축소 될 수 있습니다.

    해결책 : triggerGrid.ActualHeight = 0 일 때 dataGrid.MaxHeight 를 설정하는 DataGrid.Style ( triggerGrid 는 별 크기의 행을 triggerGrid ).

  2. 우리가 MinHeightDataGridRow 제공 할 때 dataGrid.ActualHeight 축소 될 때 축소되지 않습니다 (축소 된 높이를 다시 훔칩니다).

    해결 방법 : RowDefinition.Style : triggerGrid.ActualHeight = 0 인 경우 MinHeightdataGrid.ActualHeight 설정하고 그렇지 않으면 고정 값으로 설정합니다.

별 크기의 높이 (남은 공백)가 0이 될 때를 설명하기 위해 Controls의 BackGround 색상을 설정했습니다.

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

이것은 정확한 답변이 아닙니다. 그러나, 그것은 당신의 필요를 성취 할 아이디어를 줄 것입니다.

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

희망이 도움이됩니다.





datagrid