[英]WPF: Reference Visibility enum value in MultiBinding Binding Source
[英]WPF Binding enum to Visibility
我正在使用MVVM模式(入门)用于WPF应用程序
我在模型的Train.cs
类中定义了一个名为TrainDirection
的属性:
public enum TrainDirection
{
Unknown,
None,
Left,
Right
}
在视图中我想根据枚举的值显示/隐藏表示trainObject
的symbol
。
我创建了一个'UserControl':
<Grid >
<Path x:Name="TrainToRight" Data="M80,160L220,160 270,190 220,220 80,220" Stretch="Fill" StrokeThickness="2" Opacity="0.9"
</Path>
<Path x:Name="TrainToLeft" Data="M130,160L260,160 260,220 130,220 80,190z" Stretch="Fill" StrokeThickness="2" Opacity="0.9"
</Path>
</Grid>
我想我需要像trainDirectionToVisibilityConverter
这样的trainDirectionToVisibilityConverter
来将可见性Property绑定到TrainDirection,以便根据Direction显示/隐藏正确的符号。
我想用这种方式实现转换器:
class TrainDirectionToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var direction = (TrainDirection)value;
switch (direction)
{
case TrainDirection.Unknown:
return Application.Current.FindResource("TrainDirectionUnknown");
case TrainDirection.None:
return Application.Current.FindResource("TrainDirectionNone");
case TrainDirection.Left:
return Application.Current.FindResource("TrainDirectionLeft");
case TrainDirection.Right:
return Application.Current.FindResource("TrainDirectionRight");
default: throw new ArgumentException($"Unsupported TranDirection value: {direction}");
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
还有一个ResourceDictionary,其中为App定义了自定义样式。
我该如何实现这种绑定?
一些解释将非常有用,因为我刚刚开始使用c#和WPF编程
不需要转换器,你可以只使用数据触发器,如下所示:
<Path x:Name="TrainToRight" Data="M80,160L220,160 270,190 220,220 80,220" Stretch="Fill" StrokeThickness="2" Opacity="0.9">
<Path.Style>
<Style TargetType="{x:Type Path}">
<Setter Property="Visibility" Value="Hidden" /> <!-- default value -->
<Style.Triggers>
<DataTrigger Binding="{Binding TrainDirectionProperty}" Value="Unknown">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
每个路径必须执行一次。
或者,您也可以声明单个路径并使用DataTriggers将“Data”属性设置为您之后的路径数据:
<Path Stretch="Fill" StrokeThickness="2" Stroke="Black" Opacity="0.9">
<Path.Style>
<Style TargetType="{x:Type Path}">
<Style.Triggers>
<DataTrigger Binding="{Binding TrainDirectionProperty}" Value="Left">
<Setter Property="Data" Value="M130,160L260,160 260,220 130,220 80,190z" />
</DataTrigger>
<DataTrigger Binding="{Binding TrainDirectionProperty}" Value="Right">
<Setter Property="Data" Value="M80,160L220,160 270,190 220,220 80,220" />
</DataTrigger>
<!-- etc -->
</Style.Triggers>
</Style>
</Path.Style>
</Path>
另一种可能性是创建一个所有路径都使用的通用样式。 在这种情况下,您需要一些其他方法来区分它们,一种方法是将它们的值存储在“Tag”属性中,您可以将其用于任意自定义数据:
<Path Tag="{x:Static vm:TrainDirection.Right}" Data="M80,160L220,160 270,190 220,220 80,220" Style="{StaticResource TrainDirectionStyle}" />
<Path Tag="{x:Static vm:TrainDirection.Left}" Data="M130,160L260,160 260,220 130,220 80,190z" Style="{StaticResource TrainDirectionStyle}" />
... etc...
然后创建一个样式,将绑定值与标记中的值进行比较,并相应地设置可见性:
<Style x:Key="TrainDirectionStyle" TargetType="{x:Type Path}">
<Setter Property="Stretch" Value="Fill" />
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="Stroke" Value="Black" />
<Setter Property="Opacity" Value="0.9" />
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource EqualityConverter}">
<Binding Path="TrainDirectionProperty" />
<Binding RelativeSource="{RelativeSource Self}" Path="Tag" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
这是保证转换器的极少数情况之一,但它是一个通用的相等比较器,可用于代码的其他部分,而不是仅仅专门支持这种情况:
public class EqualityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return object.Equals(values[0], values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我的首选选项可能是#2,因为它最小化了绑定和GUI对象的数量,同时仍然相对容易阅读和理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.