我有以下一段代码。
<Button.Style>
<Style BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
TargetType="{x:Type Button}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding Status, Mode=OneWay}"
Value="{x:Static comm:DeviceStatus.Standby}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Status, Mode=OneWay}"
Value="{x:Static comm:DeviceStatus.Busy}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Status, Mode=OneWay}"
Value="{x:Static comm:DeviceStatus.Offline}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Status, Mode=OneWay}"
Value="{x:Static comm:DeviceStatus.StartingStream}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Status, Mode=OneWay}"
Value="{x:Static comm:DeviceStatus.Connecting}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Status, Mode=OneWay}"
Value="{x:Static comm:DeviceStatus.Disconnecting}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Status, Mode=OneWay}"
Value="{x:Static comm:DeviceStatus.DownloadingFiles}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
默认情况下,该按钮是隐藏的,并且当视图模型中的一个属性中只有几个值时可见。该属性是一个名为DeviceStatus的枚举类型。
基本上,它对提供的触发器执行“或”运算。 因此,按钮的可见性取决于:状态== StandBy ||状态==忙|| ...
如何在没有8个触发器的情况下实现此功能?
我想要以下内容:
<DataTrigger Binding="{Binding Status, Mode=OneWay}">
<DataTrigger.AnyValue>
<AnyValueItem Value="{x:Static comm:DeviceStatus.Standby}" />
<AnyValueItem Value="{x:Static comm:DeviceStatus.Busy}" />
<AnyValueItem Value="{x:Static comm:DeviceStatus.Offline}" />
...
</DataTrigger.AnyValue>
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
如果绑定获得任何提供的值,则将“按钮的可见性”设置为“可见”。 谢谢!
答案 0 :(得分:1)
DataTrigger
不支持某种可能的值列表。它只有一个Value
属性。
解决此问题的最简单方法是向视图模型添加一个属性,该属性返回一个指示是否显示Button
的值:
public bool IsVisible => Status == Standby || Status == Busy || ...;
XAML:
<DataTrigger Binding="{Binding IsVisible, Mode=OneWay}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
另一种选择是使用@ 33t建议的converter。然后,您只需将逻辑移出视图模型,例如:
public class Converter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ViewModel vm = value as ViewModel;
return (vm != null && (vm.Status == Standby || vm.Status == Busy || ...)) ? Vsibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML:
<Style ...>
<Style.Resources>
<local:Converter x:Key="conv" />
</Style>
<Setter Property="Visibility" Value="{Binding Path=., Converter={StaticResource converter}}" />
答案 1 :(得分:1)
您可以做一个财产:
private DeviceStatus _Status;
public DeviceStatus Status
{
get { return _Status; }
set
{
this.Set(ref _Status, value);
RaisePropertyChanged(nameof(this.StatusVisibility));
}
}
public Visibility StatusVisibility
{
get
{
switch (_Status)
{
case DeviceStatus.Busy: //add other statuses here
return Visibility.Visible;
}
return Visibility.Collapsed;
}
}
,然后在您的按钮中:
<Button Content="MyButton" Visibility="{Binding StatusVisibility}"></Button>
答案 2 :(得分:0)
阅读答案后,我有了一些想法,找到了令人满意的可扩展解决方案。
首先,我创建了以下转换器。
public sealed class EnumOrConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DeviceStatus status = (DeviceStatus)value;
DeviceStatus[] statuses = parameter as DeviceStatus[];
if (statuses.Any(s => s == status))
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
第二,我只是将以下代码添加到XAML中。
<Button Command="{Binding SomeCommand}">
<Button.Style>
<Style BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
TargetType="{x:Type Button}">
<Setter Property="Visibility">
<Setter.Value>
<Binding Path="Status" Converter="{StaticResource EnumOrConverter}">
<Binding.ConverterParameter>
<x:Array Type="{x:Type comm:DeviceStatus}">
<x:Static Member="comm:DeviceStatus.Standby" />
<x:Static Member="comm:DeviceStatus.Busy" />
<x:Static Member="comm:DeviceStatus.Offline" />
<x:Static Member="comm:DeviceStatus.StartingStream" />
<x:Static Member="comm:DeviceStatus.Connecting" />
<x:Static Member="comm:DeviceStatus.Disconnecting" />
<x:Static Member="comm:DeviceStatus.DownloadingFiles" />
</x:Array>
</Binding.ConverterParameter>
</Binding>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
这使我可以将转换器逻辑重用于许多其他按钮,而无需向ViewModel添加变量或属性。同样发生的是,转换器封装了“或:给”参数和“默认为Visibility.Collapsed”的逻辑。而且,添加新参数只需要XAML中的一行代码即可。