WPF:如何将控件绑定到由多个依赖属性组成的公式?
我正在开发ExpressionBlend,目前正在设计一个自定义控件,它有一个网格,里面有5行,还有两个依赖属性:“Value”和“Maximum”。其中三行的高度是固定的,我要做的是将其余行的高度分别设置为“Value/max”和“1-Value/max”。我该怎么做呢 当我将高度设置为“值”时,它似乎会做出反应,但当我将其设置为“值/最大值”时,它会停止工作。我对WPF还是有点陌生,所以必须有另一种方法来实现我的意图,但在搜索之后,我在其他地方找不到我的问题 代码:WPF:如何将控件绑定到由多个依赖属性组成的公式?,wpf,properties,user-controls,dependencies,Wpf,Properties,User Controls,Dependencies,我正在开发ExpressionBlend,目前正在设计一个自定义控件,它有一个网格,里面有5行,还有两个依赖属性:“Value”和“Maximum”。其中三行的高度是固定的,我要做的是将其余行的高度分别设置为“Value/max”和“1-Value/max”。我该怎么做呢 当我将高度设置为“值”时,它似乎会做出反应,但当我将其设置为“值/最大值”时,它会停止工作。我对WPF还是有点陌生,所以必须有另一种方法来实现我的意图,但在搜索之后,我在其他地方找不到我的问题 代码: (...) 顺便说一
(...)
顺便说一句,这个值总是一个不负的双精度,小于或等于最大值;所以除法的结果是0.0到1.0之间的数字。我想要一个“星形”而不是“像素”行高。您需要一个。我不确定我是否理解您在做什么,但基本上,对于XAML:
<RowDefinition>
<RowDefinition.Height>
<MultiBinding Converter={StaticResource ...}>
<Binding ElementName=UserControl, Path=Value ... />
<Binding ElementName=UserControl, Path=Maximum ... />
</MultiBinding>
</RowDefinition.Height>
</RowDefinition>
<Grid.Resources>
<localxmlns:YourNewMultiValueConverter x:Key="Whatever" />
</Grid.Resources>
这应该允许你做你想做的事
在没有intellisense的情况下键入xaml真的很糟糕这里有一个多值转换器,可以与Justablel的答案一起使用:
public class RatioStarSizing : IMultiValueConverter
{
public static readonly RatioStarSizing Instance = new RatioStarSizing();
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return new GridLength((double)values[0] / (double)values[1], GridUnitType.Star);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
这将允许您使用此XAML:
<Grid x:Name="LayoutRoot" Width="Auto" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition>
<RowDefinition.Height>
<MultiBinding Converter="{x:Static RatioStarSizing}">
<Binding ElementName="UserControl" Path="Value" />
<Binding ElementName="UserControl" Path="Maximum" />
</MultiBinding>
</RowDefinition.Height>
</RowDefinition> Height="{Binding Path=(Value/Maximum), ElementName=UserControl, Mode=Default}"/>
<RowDefinition Height="16"/>
<RowDefinition Height="*" />
<RowDefinition Height="32"/>
</Grid.RowDefinitions>
(...)
Height=“{Binding Path=(值/最大值),ElementName=UserControl,Mode=Default}”/>
(...)
请注意使用星形调整大小的巧妙技巧,以避免需要两个多值转换器:第一个元素设置为值/最大值的星形,因此如果值为4,最大值为10,转换器将重新调整“0.4*”作为大小,从而产生以下实际行高
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="0.4*"/>
<RowDefinition Height="16"/>
<RowDefinition Height="*" />
<RowDefinition Height="32"/>
</Grid.RowDefinitions>
如您所见,这将实现您需要的单多值转换器
作为一个脚注,我开发了一个我计划很快开放源码的库,它允许我以这种方式编写整个内容,而不需要转换器:
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="{edf:ExpressionBinding
new GridLength(Value/Maximum, GridUnitType.Star)"/>
<RowDefinition Height="16"/>
<RowDefinition Height="*" />
<RowDefinition Height="32"/>
</Grid.RowDefinitions>
一旦我发布这个库供公众使用,我会在这里添加一条评论。谢谢,这就是我想要的!回答得好。注意:对这种转换器使用单例模式更有效:在多值转换器中创建一个公共静态属性“实例”,如下所示:
publicYourNewMultivalueConverter实例=newYourNewMultivalueConverter()
然后在XAML中使用
引用它。这执行起来更有效,也不需要在ResourceDictionary中单独使用资源。仅供参考,我刚刚添加了一个答案,更详细地解释了我对singleton模式的评论,并展示了一种使用星形大小来实现目标的聪明方法。
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="{edf:ExpressionBinding
new GridLength(Value/Maximum, GridUnitType.Star)"/>
<RowDefinition Height="16"/>
<RowDefinition Height="*" />
<RowDefinition Height="32"/>
</Grid.RowDefinitions>