我有一个转换器,用于根据子容器的大小(父)确定子元素的大小。
<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;
}
}
但是,当我这样做时,尺寸永远不会改变。似乎控件一次传递到了转换器,但从未更新。我想这与通过引用传递而不是通过值传递有关。或类似的东西。
我知道我可以使用MultiBinding
和IMultiValue Converter
将多个值传递给转换器,但是由于我想要的所有值已经包装在一个漂亮的小对象(控件)中,因此这样,将xaml绑定起来会更加整洁。
如何通过控件进行更新?
答案 0 :(得分:1)
仅当您实际绑定到的属性设置为新值时,才调用转换器。
这意味着您无法绑定到rowsContainer
控件本身,因为ActualWidth
或ActualHeight
属性更新时它永远不会绑定。
前往MultiBinding
或ActualWidth
的{{1}}是这里的方法。
如何通过控件进行更新?
您不能出于已经提到的原因。
答案 1 :(得分:1)
似乎控件一次传递到了转换器,但从未更新。我想这与通过引用传递而不是通过值传递有关。
WPF中的属性更新不是魔术,代码必须显式调用WPF以告知其值已更新。
绑定ActualWidth
时,实际上这是一个依赖项属性,其事件已更改,WPF可以挂接到该事件,并通过更改代码来通知它。但是,当您绑定控件本身时,它不是依赖项属性,并且控件未实现INotifyPropertyChanged
,因此WPF永远都不知道其属性已更改。
我知道我可以使用MultiBinding和IMultiValue Converter将多个值传递给转换器,但是[...]
MultiBinding
允许您绑定到多个依赖项属性,并使WPF一次侦听其所有属性更改通知。我在“但是”处停止了引号,因为无论随后发生什么,这都是您需要做的。