DataGrid RowDetails 宽度问题
假设我有一个像这样定义的 DataGrid
<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
在右侧的图片中我得到一个非常长的 DataGridRow,它永远不会换行。
是否可以让 RowDetails 使用与 DataGrid 相同的宽度而不影响宽度本身?
我尝试过实现换行,但没有以令人满意的方式
- 设置边框或文本块的宽度或最大宽度。不是很有活力。
- 在 DataGrid 上设置 ScrollViewer.HorizontalScrollBarVisibility="Disabled"。当列不适合时效果不太好。
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>
And looks like this with and without RowDetails
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
- Set Width or MaxWidth on the Border or the TextBlock. Not very dynamic.
- Set ScrollViewer.HorizontalScrollBarVisibility="Disabled" on the DataGrid. Not very good when the columns doesn't fit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这里的答案感觉像是一个解决方法,所以我做了一些研究,并在 Telerik 论坛上找到了解决方案,因为我们使用他们的 RadGridView。事实证明该解决方案也适用于 DataGrid。
关键是将 ScrollViewer.HorizontalScrollBarVisibility 属性设置为“Disabled”,请参见下面的示例。
编辑:
副作用是,如果列需要的水平空间多于可用空间,它们将被剪裁。因此,如果这是一个问题,那么这个解决方案并不是最佳的。
The answers here felt like a workaround so I did some research and did find the solution on the Telerik forums, since we use their RadGridView. Turned out the solution worked for DataGrid as well.
The key is to set the ScrollViewer.HorizontalScrollBarVisibility property to Disabled, see example below.
Edit:
A side effect is that if the columns needs more space horizontally than there are room for they will be clipped. So if this is a problem then this solution isn't optimal.
这就是我最终所做的。我宁愿使用 DataGrid 上的属性来实现此目的,但由于不存在这样的属性,我需要一个解决方法。
首先,我只是使用父 DataGrid 中的 ActualWidth 并删除了常量 9。这起初有效,但当垂直滚动条变得可见,因此我不得不使用 MultiBinding。
在转换器中,我使用另一个常量 (16) 来补偿可见的垂直滚动条(如果它可见)。
更新
我对解决方案进行了一些改进,对 ItemsPresenter 使用 ActualWidth 而不是 DataGrid(其中 ActualWidth 不会根据可见的 ScrollBar 改变),从而消除了对 MultiConverter 和两个常量的需要。
减去常数转换器
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.
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.
And in the converter I used another constant (16) to compensate for a visible vertical scrollbar (if it's visible).
Update
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.
SubtractConstantConverter
这就是我最终要做的:将行详细信息宽度绑定到其呈现器的实际宽度,然后添加具有不同厚度的边框以补偿呈现器中存在/不存在垂直滚动条。这种方法对我来说非常有效。示例 xaml:
This is what I ended up doing: binding of the row details width to the actual width of its presenter and then added a border with a varied thickness to compensate for the presence/absence of a vertical scroll-bar in the presenter. This approach worked perfectly for me. Sample xaml:
您可以将 MaxWidth 绑定到 ElementName=PART_ColumnHeadersPresenter、Path=ActualWidth 或 RenderSize.Width。我相信这是显示列的 DataGrid 模板的一部分,因此理论上它应该可以工作
You might be able to bind the MaxWidth to
ElementName=PART_ColumnHeadersPresenter, Path=ActualWidth
or perhaps RenderSize.Width. I believe that is the part of the DataGrid Template that displays the columns so in theory it should work感谢 Meleak,您的解决方案对我来说效果很好。为我们 WPF 新手添加的一小部分。请务必将 Converter 类声明为资源,以便可以在 Binding 表达式中引用它。
我把我的放在 App.Xaml 中,如下所示:
Thanks Meleak, your solution worked well for me. One small addition for us WPF newbies. Be sure to declare your Converter class as a resource so it can be referenced in the Binding expression.
I put mine in App.Xaml like this:
为了节省其他人一些头痛和试错的时间:
在对 Fredrik Hedblad 的最新 (1/1/11) 解决方案大惊小怪之后 一段时间我发现 ConverterParameter 值应该是 6 + [left margin} + [right margin] (即最外层容器的边距)模板。)在检查了屏幕截图的放大后,我预计 6 是每行左侧垂直条的宽度。
To save other folks some head scratching and trial-and-error time:
After fussing with Fredrik Hedblad's most recent (1/1/11) solution for some time I figured out that the ConverterParameter value should be 6 + [left margin} + [right margin] (i.e. margins of the outermost container in the template.) After examining a blowup of a screen shot, I expect the 6 is the width of the vertical bar at the left of each row.