DataGrid RowDetails 宽度问题 [英] DataGrid RowDetails Width problem
问题描述
假设我有一个这样定义的 DataGrid
Suppose I have a DataGrid that is defined like this
<DataGrid AreRowDetailsFrozen="True"
ItemsSource="{Binding MyCollection}"
AutoGenerateColumns="False">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border CornerRadius="5" BorderBrush="Red"
BorderThickness="2" Background="Black">
<TextBlock Foreground="White" Text="{Binding RowDetails}"
TextWrapping="Wrap"/>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
<DataGrid.Columns>
<DataGridTextColumn Header="0" Binding="{Binding Value1}"/>
<DataGridTextColumn Header="1" Binding="{Binding Value2}"/>
<DataGridTextColumn Header="2" Binding="{Binding Value3}"/>
<DataGridTextColumn Header="3" Binding="{Binding Value4}"/>
</DataGrid.Columns>
</DataGrid>
看起来像这样,有和没有 RowDetails
And looks like this with and without RowDetails
在右边的图片中,我得到了一个非常长的 DataGridRow,它从不换行.
是否可以让 RowDetails 使用与 DataGrid 相同的宽度而不影响宽度本身?
In the picture to the right I get a very long DataGridRow that never wraps.
Is it possible to get the RowDetails to use the same width as the DataGrid and not effect the Width itself?
我尝试过的可以实现包装但不令人满意的方法
Things I have tried that achieves wrapping but not in a satisfying way
- 在边框或 TextBlock 上设置 Width 或 MaxWidth.不是很动态.
- 在 DataGrid 上设置 ScrollViewer.HorizontalScrollBarVisibility="Disabled".当列不适合时效果不佳.
推荐答案
这就是我最终要做的.为此,我宁愿在 DataGrid 上使用一个属性,但由于不存在这样的属性,因此我需要一种解决方法.
This is what I ended up doing. I'd rather use a Property on the DataGrid for this but since no such Property exist I needed a workaround.
首先,我只使用了父 DataGrid 中的 ActualWidth 并删除了一个常量 9.这起初有效,但当垂直滚动条变得可见时失败了,因此我不得不使用 MultiBinding.
First I just used ActualWidth from the parent DataGrid and removed a constant of 9. This worked at first but failed when the vertical scrollbar became visible so I had to use a MultiBinding.
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border HorizontalAlignment="Left" CornerRadius="5"
BorderBrush="Red" BorderThickness="2" Background="Black">
<Border.Width>
<MultiBinding Converter="{StaticResource RowDetailsWidthMultiConverter}"
ConverterParameter="9">
<Binding RelativeSource="{RelativeSource AncestorType={x:Type DataGrid}}"
Path="ActualWidth"/>
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ScrollViewer}}"
Path="ComputedVerticalScrollBarVisibility"/>
</MultiBinding>
</Border.Width>
<TextBlock Foreground="White" Text="{Binding RowDetails}" TextWrapping="Wrap"/>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
在转换器中,我使用了另一个常量 (16) 来补偿可见的垂直滚动条(如果它可见).
And in the converter I used another constant (16) to compensate for a visible vertical scrollbar (if it's visible).
public class RowDetailsWidthMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double originalWidth = (double)values[0];
Visibility verticalScrollbarVisibility = (Visibility)values[1];
double subtractWidth = System.Convert.ToDouble(parameter);
double returnWidth = originalWidth - subtractWidth;
if (verticalScrollbarVisibility == Visibility.Visible)
{
return returnWidth - 16;
}
return returnWidth;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
<小时>
更新
我稍微改进了解决方案,将 ActualWidth 用于 ItemsPresenter 而不是 DataGrid(其中 ActualWidth 不会根据可见的 ScrollBar 改变),从而消除了对 MultiConverter 和两个常量的需要.
I improved on the solution a bit, using ActualWidth for the ItemsPresenter rather then DataGrid (where ActualWidth didn't change depending on a visible ScrollBar), thus removing the need for a MultiConverter and two constants.
<DataGrid.Resources>
<local:SubtractConstantConverter x:Key="SubtractConstantConverter"/>
</DataGrid.Resources>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border HorizontalAlignment="Left" CornerRadius="5"
BorderBrush="Red" BorderThickness="2" Background="Black"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsPresenter}},
Path=ActualWidth,
Converter={StaticResource SubtractConstantConverter},
ConverterParameter=6}">
<TextBlock Foreground="White" Text="{Binding RowDetails}" TextWrapping="Wrap"/>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
SubtractConstantConverter
public class SubtractConstantConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double originalValue = (double)value;
double subtractValue = System.Convert.ToDouble(parameter);
return originalValue - subtractValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
这篇关于DataGrid RowDetails 宽度问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!