我正在研究Expression Blend,我正在设计一个自定义控件,里面有一个包含5行的Grid,还有两个Dependency属性:“Value”和“Maximum”。其中三行具有固定高度,我想要做的是将剩余行高分别设置为“值/最大值”和“1值/最大值”。我该怎么做呢?
当我将高度设置为“值”时,似乎会做出反应,但当我将其设置为“值/最大值”时,它会停止工作。我仍然对WPF有点新意,所以必须有另一种方法来实现我的意图,但在搜索后我不会在其他地方找到我的问题。
代码:
<Grid x:Name="LayoutRoot" Width="Auto" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="{Binding Path=(Value/Maximum), ElementName=UserControl, Mode=Default}"/>
<RowDefinition Height="16"/>
<RowDefinition Height="{Binding Path=(1-Value/Maximum), ElementName=UserControl, Mode=Default}"/>
<RowDefinition Height="32"/>
</Grid.RowDefinitions>
(...)
顺便说一句,Value总是不是负二倍小于或等于最大值;所以除法的结果将是0.0到1.0之间的数字。我想要一个“星”而不是“像素”行高。
答案 0 :(得分:3)
您需要MultiValueConverter。我不确定我理解你在做什么,但基本上,对于XAML:
<RowDefinition>
<RowDefinition.Height>
<MultiBinding Converter={StaticResource ...}>
<Binding ElementName=UserControl, Path=Value ... />
<Binding ElementName=UserControl, Path=Maximum ... />
</MultiBinding>
</RowDefinition.Height>
</RowDefinition>
然后在代码中,您需要声明一个实现IMultiValueConverter
的类,并且在Convert
方法中,values
将包含各种正常Binding
的事物列表返回(0是最高的一个(这里是值),1是下一个,等等)。最后,您只需要将新类的StaticResource添加到XAML:
<Grid.Resources>
<localxmlns:YourNewMultiValueConverter x:Key="Whatever" />
</Grid.Resources>
这应该允许你做你想做的事。
在没有intellisense的情况下输入xaml真的很糟糕
答案 1 :(得分:1)
这是一个MultiValueConverter,您可以使用JustABill的答案:
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>
(...)
注意使用星形大小以避免需要两个MultiValueConverters的聪明技巧:第一个元素设置为值/最大值的星号,因此如果Value为4且Maximum为10,则转换器将返回“0.4 *”作为大小,导致以下实际行高。
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="0.4*"/>
<RowDefinition Height="16"/>
<RowDefinition Height="*" />
<RowDefinition Height="32"/>
</Grid.RowDefinitions>
正如您所看到的,这将通过单个MultiValueConverter实现您所需的功能。
作为一个脚注,我开发了一个我计划很快开源的库,这样我就可以用这种方式编写完整的东西而无需转换器:
<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>
我发布此库供公众使用后,我会在此处添加评论。