我要做的是:
<Grid>
<Grid.RowDefinitions>
...
<!--The next line is pseudo code for what I am trying to achieve-->
<RowDefintion Height="if(EditEnabled) { 10* } else { 0 }" />
...
</Grid.RowDefinition>
...
<DockPanel Visibility="{Binding EditEnabled, Converter={StaticResource InverseBooleanToVisibilityConverter}}" ...>
...
我正在尝试更改DockPanel的可见性,具体取决于是否启用了编辑,同时保持其调整大小并具有固定高度和相对高度的能力。
问题:
是否有IValueConverter
(System.Windows.Data.IValueConverter
)可以采用布尔值和两个数字并根据布尔值选择GridLength
之一?从检查IValueConverter
的界面开始,它看起来不是一个非常合适的类型。
或者有更好的方法来注入我想要的GridLength
吗?
我尝试了什么:
IValueConverter
的继承人 - 对我来说没什么好看的Height="10*"
标记内移动DockPanel
并将RowDefinition
更改为Auto
- 这会产生转化例外答案 0 :(得分:4)
不幸的是,if-then没有IValueConverter
(更具体地说:你不能用XAML做if-then逻辑)
但是你可以在C#代码中执行if-then逻辑
这是解决方案
public class HeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool enableEdit = (bool)value;
double param = System.Convert.ToDouble(parameter);
if (enableEdit)
return new GridLength(param, GridUnitType.Star);
else
return new GridLength(0);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
和这样的窗口。
<Window.Resources>
<local:HeightConverter x:Key="heightConverter"/>
<sys:Int32 x:Key="param">10</sys:Int32>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding Path=EditEnabled, Converter={StaticResource heightConverter}, ConverterParameter={StaticResource param}}" />
</Grid.RowDefinitions>
</Grid>
请考虑定义您将使用的所需命名空间,如下所示
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:[your namespace]"
可以获得相同的结果
public class HeightMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool enableEdit = (bool)values[0];
double param = System.Convert.ToDouble(values[1]);
if (enableEdit)
return new GridLength(param, GridUnitType.Star);
else
return new GridLength(0);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
和这样的窗口
<Window.Resources>
<local:HeightMultiConverter x:Key="heightMutliConverter"/>
<sys:Int32 x:Key="param">10</sys:Int32>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition >
<RowDefinition.Height>
<MultiBinding Converter="{StaticResource heightMutliConverter}">
<Binding Path="EditEnabled"/>
<Binding Source="{StaticResource param}"/>
</MultiBinding>
</RowDefinition.Height>
</RowDefinition>
</Grid.RowDefinitions>
</Grid>
注意:请不要忘记,您必须通过设置Source
属性来处理DataContext
。
答案 1 :(得分:1)
您可以使用内置转换器:AlternationConverter
。您指定值列表(任意类型),绑定到整数,转换器在值列表中查找整数(以值计数为模)。
如果您为此AlternationConverter
指定了两个值,并且您能够将EditEnabled
属性提供为整数0
或1
,那么您可以将0
和1
映射到您想要的任何值。
如果您觉得将bool
转换为整数(我可以同情的话)是没有意义的,您仍然可以使用AlternationConverter
作为自定义转换器的灵感来源不要求模型值为int
类型。
答案 2 :(得分:1)
按照http://stackoverflow.com/a/5182660/469708所述创建BooleanConverter<T>
基类
public class BooleanConverter<T> : IValueConverter
{
public BooleanConverter(T trueValue, T falseValue)
{
True = trueValue;
False = falseValue;
}
public T True { get; set; }
public T False { get; set; }
public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is bool && ((bool) value) ? True : False;
}
public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is T && EqualityComparer<T>.Default.Equals((T) value, True);
}
}
然后写
public class BooleanToGridLengthConverter : BooleanConverter<System.Windows.GridLength>
{
public BooleanToGridLengthConverter() : base(
new System.Windows.GridLength(1, System.Windows.GridUnitType.Star),
new System.Windows.GridLength(0))
{
}
}
可以直接设置true和false的值,不需要MultiValueConverter(只要仅布尔参数需要可绑定)。
<convert:BooleanToGridLengthConverter x:Key="Converter" True="10*" False="0" />
或者,您可以从MarkupExtension派生转换器,并像这样直接使用它:
<RowDefinition Height="{Binding EditEnabled, Converter={convert:BooleanToGridLengthConverter True=10*, False=0}" />