用户使用 GridSplitter 后 WPF 行高绑定停止工作
Posted
技术标签:
【中文标题】用户使用 GridSplitter 后 WPF 行高绑定停止工作【英文标题】:WPF row height binding stops working after user uses GridSplitter 【发布时间】:2013-12-06 02:41:40 【问题描述】:我有一个四行网格:
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Binding DocumentsHeight"/>
<RowDefinition Height="Auto"/> - GRIDSPLITTER
<RowDefinition Height="Binding ApprovedDocumentsHeight" />
</Grid.RowDefinitions>
行的动态调整大小可以正常工作,高度绑定到具有“5*”等值的字符串。但是当用户使用 GridSplitter 时,绑定停止工作,当我想更改行的大小时,在下一次通知后不会调用 getter。有谁知道问题出在哪里?
感谢您的帮助。
【问题讨论】:
【参考方案1】:如果网格宽度或高度绑定到 ViewModel(实现 INPC)中的 GridLength
属性,则正确的转换器是:
public class GridLengthConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture) => value;
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture) => value;
在视图中绑定是这样的(这里是行高,但它可以是另一个属性):
<RowDefinition Height="Binding TopLength, Mode=TwoWay,
Converter=StaticResource GridLengthConverter"/>
在资源字典中,converters
将映射到类GridLengthConverter
所在的命名空间:
<converters:GridLengthConverter x:Key="GridLengthConverter" />
【讨论】:
【参考方案2】:可重复使用的解决方案是使用转换器...
public class DoubleToGridLengthConverter : IValueConverter
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
if (value is double len)
return new GridLength(len, GridUnitType.Pixel);
return new GridLength(0, GridUnitType.Auto);
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
return value is GridLength ? ((GridLength)value).Value : 0;
【讨论】:
【参考方案3】:如果您绑定到除 GridLength 之外的任何内容,则绑定将中断。 您可以像这样绑定到 GridLength 属性...
private double documentsHeight = 100;
public GridLength DocumentsHeight
get return this.GridLength(this.documentsHeight);
set this.documentsHeight = value.Value;
您还需要在绑定上设置 Mode=TwoWay。
【讨论】:
完全正确。您也可以使用 IValueConverter 在 double 和 GridLength 之间进行转换。【参考方案4】:所以我通过将绑定设置为具有双向模式的 GridLength 属性来使其工作。这样,网格拆分器会正确设置值并且绑定不会中断。
【讨论】:
【参考方案5】:为了发挥它的魔力,拆分器通过将 Height 属性设置为显式值来调整其上方行的高度。这会导致调用 SetValue,从而从属性中删除绑定。您必须手动恢复绑定以使用更改通知来更新行大小,但如果您这样做,那么您可能只想考虑直接设置高度而不是使用绑定。或者,您可以创建自己的拆分器,在 Height 属性上使用 SetCurrentValue,这不会覆盖现有绑定。
【讨论】:
所以我通过将绑定设置为具有双向模式的 GridLength 属性来使其工作。这样,网格拆分器会正确设置值并且绑定不会中断。 在gridsplitter后代中,如何调用SetCurrentValue并防止SetValue被调用? 不要做 gridsplitter 后代,做一个替换控件。【参考方案6】:可能有很多东西。拆分器必须“接管”行/列定义才能更改宽度/高度。这可能会导致绑定被删除。探索代码并确切了解发生了什么需要一些时间,但这毫无意义,因为我们已经知道它会失败。
因此,您可能无法轻松地做您想做的事。如果是我,我会通过将其包装在 UserControl
中来表达我想要的功能。在 DocumentsHeight 和 ApprovedDocumentsHeight 的 UserControl 上公开 DependencyProperties
。我会将change event handlers 添加到这些属性中,然后从控件的代码隐藏中适当地调整拆分器位置。
【讨论】:
我刚刚发现它可能有效,如果我绑定到 GridLength 而不是字符串,我会先尝试。以上是关于用户使用 GridSplitter 后 WPF 行高绑定停止工作的主要内容,如果未能解决你的问题,请参考以下文章
wpf中的grid使用分割器GridSplitter 为啥拉不动