为啥 WPF/XAML 绑定使用 x:Reference 气质?

Posted

技术标签:

【中文标题】为啥 WPF/XAML 绑定使用 x:Reference 气质?【英文标题】:Why is WPF/XAML Binding using x:Reference temperamental?为什么 WPF/XAML 绑定使用 x:Reference 气质? 【发布时间】:2021-03-16 11:49:41 【问题描述】:

我有一个 WPF/XAML DataGrid,其中一列包含图像。我希望该列的宽度(以及图像的大小)由不在 DataGrid 中的 Slider 控制。 (我知道这本身就存在问题,但我找到了一个很好的解决方案here。)问题是,滑块值和列宽度之间的绑定似乎非常脆弱。如果用户调整父窗口的大小,导致 DataGrid 调整大小,则绑定会中断。如果我在 DataGrid 中设置 VerticalScrollBarVisibility="Auto",然后用户调整滑块以使 DataGrid 的滚动条需要出现,那么绑定就会中断。一旦绑定被破坏,除非用户关闭窗口并重新打开它,否则它不会再回来。

这里是相关的 DataGrid 列定义:

<DataGridTemplateColumn Width="Binding Source=x:Reference PictureSizeSlider, Path=Value">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Image Name="ImageBox" Stretch="Uniform" Source="Binding Image"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

这里是 Slider 的定义(在不同的 Grid 中):

<Slider Grid.Column="1" Name="PictureSizeSlider" Minimum="10" Maximum="255" Value="100" IsMoveToPointEnabled="True"/>

谁能告诉我为什么绑定如此脆弱,以及如何使它变得健壮?

【问题讨论】:

【参考方案1】:

使用在DataGridLengthdouble 之间转换的绑定转换器:

public class DataGridLengthConverter : IValueConverter

    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    
        var length = (DataGridLength)value;
        return length.UnitType == DataGridLengthUnitType.Pixel ? length.Value : 0d;
    

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    
        return new DataGridLength((double)value);
    

将其应用于 Slider 的 Value 属性的绑定:

<DataGridTemplateColumn x:Name="imageColumn" Width="100">
    ...
</DataGridTemplateColumn>

<Slider Value="Binding Width, 
                ElementName=imageColumn,
                Converter=StaticResource DataGridLengthConverter" .../>

与您原来的 Binding 相比,这个是 TwoWay,因此可以双向工作,即当您操作 Slider 或 DataGrid 列时。

当绑定属性由 Binding 以外的源设置时,将替换 OneWay Binding,例如直接设置的属性值。

【讨论】:

太棒了!谢谢。你能解释一下为什么将 Slider Value 绑定到 DataGrid Column Width 很重要,而不是仅仅规定我使用的 Binding 应该是双向的吗?你的做法与我的做法相反,这似乎违反直觉。 我选择这种方式是为了避免x:Reference ...。然而,它也应该反过来工作,但你必须明确设置Mode=TwoWay 您能解释一下为什么 x:Reference ... 是一个糟糕的选择并且应该避免吗? 并非如此。这似乎并不常见。

以上是关于为啥 WPF/XAML 绑定使用 x:Reference 气质?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 WPF/XAML 中绑定背景颜色?

WPF XAML - 将数据网格列绑定到外键(数据集)

WPF XAML 绑定和 CurrentCulture 显示

WPF XAML 绑定中的自动字段更新 - 简单示例不起作用

列表视图中的文本块不显示绑定数据 - WPF XAML

将 wpf xaml 图像绑定到 System.Windows.Controls.Image 不起作用