DataGrid RowDetails 宽度问题 [英] DataGrid RowDetails Width problem

查看:19
本文介绍了DataGrid RowDetails 宽度问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个这样定义的 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.Horizo​​ntalScrollBarVisibility="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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆