【问题标题】: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"/>

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

【问题讨论】:

    标签: wpf xaml data-binding datagrid controls


    【解决方案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 ...} 是一个糟糕的选择并且应该避免吗?
    • 并非如此。这似乎并不常见。
    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 2013-01-15
    • 2010-10-01
    • 2016-03-10
    • 2017-08-20
    • 2011-02-28
    相关资源
    最近更新 更多