바인딩 - wpf datagrid 예제
스케일링 순서 변경 WPF (2)
일종의 응답 성이 필요한 WPF 응용 프로그램이 있습니다. 내가 갖고 싶은 것은 Grid
내부의 DataGrid
입니다. 창 크기가 축소되면 Grid
크기를 먼저 조정 한 다음 DataGrid
크기를 조정합니다. 내가 지금까지 성취 한 것은 다음과 같습니다.
맨 위에있는 gif에서 Grid
먼저 크기 조정되고, 크기가 최소 크기에 도달하면 Grid
가 DataGrid
넘는 것을 볼 수 있습니다. 레이아웃을 먼저 크기 조절 한 다음 레이아웃 대신 DataGrid
스크롤 막대를 표시하고 싶기 때문에 원하는 부분이 아닙니다. 그래서 나는 다음을 시도했다.
바로 여기에서 원하는대로 스크롤바가 표시되는지 확인할 수 있습니다. 유일한 것은 DataGrid의 크기를 먼저 조절하고 DataGrid의 크기가 조정되면 Grid의 크기가 조정되기 때문입니다. 다른 방법으로, 그리드의 크기를 먼저 조정 한 다음 DataGrid의 크기를 조정하고 스크롤 막대를 표시하고 싶습니다. 그래서 기본적으로 다음을 수행하는 솔루션을 찾고 있습니다.
- 그리드의 크기를 조절하는 창 크기를 조절하십시오.
- 최소 크기가 될 때까지 눈금을 조정하십시오.
- 최소 크기에 도달 했는데도 여전히 작아지면 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>
기본 방정식 블록을 사용하여 레이아웃 방정식을 더 이상 해결할 수없는 경우 직접 계산을 수행 할 수 있습니다. 변환기가 남은 사용 가능한 공간을 계산하도록합니다.
나머지 문제는 두 가지입니다.
별 크기의 행에
ActualHeight
0이있는 경우에만DataGrid
가 축소 될 수 있습니다.해결책 :
triggerGrid.ActualHeight
= 0 일 때dataGrid.MaxHeight
를 설정하는DataGrid.Style
(triggerGrid
는 별 크기의 행을triggerGrid
).우리가
MinHeight
를DataGridRow
제공 할 때dataGrid.ActualHeight
축소 될 때 축소되지 않습니다 (축소 된 높이를 다시 훔칩니다).해결 방법 :
RowDefinition.Style
:triggerGrid.ActualHeight
= 0 인 경우MinHeight
를dataGrid.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>
희망이 도움이됩니다.