绑定DataGrid列ActualWidth设置Expander的TextBlock宽度无效,求排查
问题:Expander中TextBlock绑定DataGrid列ActualWidth未生效的原因及解决办法
你遇到的这个绑定失效问题,核心原因其实是DataGrid的列对象(比如你的colTimeAlarm)并不属于WPF的可视化树——它只是DataGrid的逻辑列定义,不是UI元素,而ElementName绑定是基于命名范围(Name Scope)和可视化树上下文来查找目标的,所以GroupItem模板里的TextBlock根本找不到这个列对象。
另外,GroupStyle的ContainerStyle是在GroupItem的模板内部,它的命名范围和DataGrid的命名范围是分开的,哪怕colTimeAlarm是可视化元素,ElementName绑定也跨不过这个命名范围的边界。
下面给你几个可行的解决办法:
方法一:通过DataGrid引用绑定列的ActualWidth
直接绑定到DataGrid的Columns集合里的目标列,用x:Reference或者RelativeSource找到DataGrid,然后指定列的命名索引定位:
<TextBlock Width="{Binding Path=Columns[colTimeAlarm].ActualWidth, Source={x:Reference GridData}}" Background="Azure" Text="{Binding StringFormat=hh\:mm\:ss, Converter={StaticResource SumTimes}, ConverterParameter=TimeAlarm}" />
如果遇到循环引用警告,可以改用RelativeSource的方式:
<TextBlock Width="{Binding Path=Columns[colTimeAlarm].ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Background="Azure" Text="{Binding StringFormat=hh\:mm\:ss, Converter={StaticResource SumTimes}, ConverterParameter=TimeAlarm}" />
方法二:借助ViewModel中转列宽
如果你的DataGrid已经绑定了ViewModel,可以在ViewModel里添加一个属性来同步列宽:
- 在ViewModel中添加带通知的属性(假设实现了
INotifyPropertyChanged):
private double _timeAlarmColumnWidth; public double TimeAlarmColumnWidth { get => _timeAlarmColumnWidth; set => SetProperty(ref _timeAlarmColumnWidth, value); }
- 修改DataGridTextColumn的Width绑定,让列宽同步到ViewModel:
<DataGridTextColumn Width="{Binding TimeAlarmColumnWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" MinWidth="80" Binding="{Binding Data, UpdateSourceTrigger=PropertyChanged}" Header="@_151_Data" Foreground="Black" IsReadOnly="True" x:Name="colTimeAlarm" />
- 让TextBlock绑定ViewModel的这个属性:
<TextBlock Width="{Binding DataContext.TimeAlarmColumnWidth, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Background="Azure" Text="{Binding StringFormat=hh\:mm\:ss, Converter={StaticResource SumTimes}, ConverterParameter=TimeAlarm}" />
额外提示
绑定ActualWidth后,你可能会发现TextBlock和列的宽度有细微偏差,这是因为DataGrid列的ActualWidth包含了列边框、内边距等额外空间。如果需要完全对齐,可以给TextBlock的Width绑定加上一个转换器,减去相应的边距值(比如2-4像素)。
内容的提问来源于stack exchange,提问作者John Goodman
相关产品推荐
相关产品推荐

