将控制权传递给按值绑定

时间:2020-06-18 14:27:08

标签: wpf

我有一个转换器,用于根据子容器的大小(父)确定子元素的大小。

<Setter Property="Width" Value="{Binding ActualWidth, ElementName=rowsContainer, 
                                 Converter={StaticResource sizer}}"/>
public class CellSizeConverter : IValueConverter
{
    private readonly int _maxNum = 7;
    private readonly int _margin = 0;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }
        double width = (double)value;
        return (width / _maxNum) - _margin;
    }
}

这有效,当我调整窗口大小时,组件的大小也会改变。哇!

我也想考虑高度,因此我尝试传递控件本身,并在转换器内部获取其属性:

<Setter Property="Width" Value="{Binding ElementName=rowsContainer, Converter={StaticResource sizer}}"/>
public class CellSizeConverter : IValueConverter
{
    private readonly int _maxNum = 7;
    private readonly int _margin = 0;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }
        ItemsControl rowsContainer = (ItemsControl)value;
        return (rowsContainer.ActualWidth / _maxNum) - _margin;
    }
}

但是,当我这样做时,尺寸永远不会改变。似乎控件一次传递到了转换器,但从未更新。我想这与通过引用传递而不是通过值传递有关。或类似的东西。

我知道我可以使用MultiBindingIMultiValue Converter将多个值传递给转换器,但是由于我想要的所有值已经包装在一个漂亮的小对象(控件)中,因此这样,将xaml绑定起来会更加整洁。

如何通过控件进行更新?

2 个答案:

答案 0 :(得分:1)

仅当您实际绑定到的属性设置为新值时,才调用转换器。

这意味着您无法绑定到rowsContainer控件本身,因为ActualWidthActualHeight属性更新时它永远不会绑定。

前往MultiBindingActualWidth的{​​{1}}是这里的方法。

如何通过控件进行更新?

您不能出于已经提到的原因。

答案 1 :(得分:1)

似乎控件一次传递到了转换器,但从未更新。我想这与通过引用传递而不是通过值传递有关。

WPF中的属性更新不是魔术,代码必须显式调用WPF以告知其值已更新。

绑定ActualWidth时,实际上这是一个依赖项属性,其事件已更改,WPF可以挂接到该事件,并通过更改代码来通知它。但是,当您绑定控件本身时,它不是依赖项属性,并且控件未实现INotifyPropertyChanged,因此WPF永远都不知道其属性已更改。

我知道我可以使用MultiBinding和IMultiValue Converter将多个值传递给转换器,但是[...]

MultiBinding允许您绑定到多个依赖项属性,并使WPF一次侦听其所有属性更改通知。我在“但是”处停止了引号,因为无论随后发生什么,这都是您需要做的。