是否有一个IValueConverter可以执行if-then
本文关键字:执行 if-then 有一个 IValueConverter 是否 | 更新日期: 2023-09-27 18:25:05
我要做的事情:
<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
,这创建了一个转换异常 - 在此处搜索
不幸的是,没有IValueConverter
可以执行if-then
(更具体地说:您不能使用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]"
更新使用IMutliValueConverter 可以获得相同的结果
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>
注意:不要忘记,您必须通过设置DataContext
属性来处理Source
。
您可以使用内置转换器:AlternationConverter
。指定一个值列表(任意类型),绑定到一个整数,转换器在值列表中查找该整数(以值计数为模)。
如果为此AlternationConverter
指定两个值,并且能够将EditEnabled
属性提供为整数0
或1
,则可以将该0
和1
映射到所需的任何值。
如果您觉得先将bool
转换为整数没有意义(我对此表示赞同),您仍然可以使用AlternationConverter
作为定制转换器的灵感,该转换器不需要模型值为int
类型。
如中所述创建BooleanConverter<T>
基类http://stackoverflow.com/a/5182660/469708
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}" />