L'écriture d'un convertisseur pour chaque règle place deux fois votre logique métier (dans le convertisseur et le modèle de vue). Je suggère de créer une propriété/un indicateur pour chaque contrôle dans votre ViewModel avec des événements INotifyPropertyChanged pour décider si le contrôle est visible (ou un autre comportement). Notez que lorsque vous regardez mon modèle (ci-dessous), vous verrez que j'expose des propriétés de type bool et Visibilty.
Si vous avez besoin d'utiliser la propriété en règle générale, utilisez bool et DataTrigger.
public bool ControlD
Si vous avez seulement besoin de contrôler la visibilité que vous pouvez lier à la visibilité directe:
public Visibility ControlA
MISE À JOUR: En raison du commentaire par @Wallstreet programmeur, j'ai ajouté une autre option d'utiliser un BooleanVisibilityConverter . J'ai mis à jour le cinquième contrôle ci-dessous pour refléter l'utilisation d'un convertisseur. J'ai ajouté le code pour le convertisseur en bas.
Voici une fenêtre de test en XAML:
<Window x:Class="ControlVisibleTrigger.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Main Window" Height="400" Width="800">
<Window.Resources>
<Style x:Key="DropDownStyle" TargetType="TextBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ControlC}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<DockPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<CheckBox IsChecked="{Binding Path=Alpha,Mode=TwoWay}" Content="Alpha"/>
<CheckBox IsChecked="{Binding Path=Beta,Mode=TwoWay}" Content="Beta"/>
<CheckBox IsChecked="{Binding Path=Gamma,Mode=TwoWay}" Content="Gamma"/>
<CheckBox IsChecked="{Binding Path=Delta,Mode=TwoWay}" Content="Delta"/>
</StackPanel>
<TextBox Grid.Row="1" Visibility="{Binding Path=ControlA}" Text="Binding to visibility"/>
<Button Grid.Row="2" Visibility="{Binding Path=ControlB}" Content="Binding to visibility"/>
<TextBox Grid.Row="3" Style="{StaticResource DropDownStyle}" Text="Using WindowResource DataTrigger"/>
<TextBox Grid.Row="4" Text="Using Local DataTrigger">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ControlD}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<Button Grid.Row="5"
Content="Press me"
Visibility="{Binding Path=ControlE, Converter={StaticResource booleanVisibilityConverter}, ConverterParameter=True, Mode=OneWay}">
</Grid>
</DockPanel>
</Window>
Voici le ViewModel:
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
}
private bool _alpha = true;
public bool Alpha
{
get
{
return _alpha;
}
set
{
_alpha = value;
OnPropertyChanged("ControlA");
OnPropertyChanged("ControlB");
OnPropertyChanged("ControlC");
OnPropertyChanged("ControlD");
OnPropertyChanged("ControlE");
}
}
private bool _beta = true;
public bool Beta
{
get
{
return _beta;
}
set
{
_beta = value;
OnPropertyChanged("ControlA");
OnPropertyChanged("ControlB");
OnPropertyChanged("ControlC");
OnPropertyChanged("ControlD");
OnPropertyChanged("ControlE");
}
}
private bool _gamma = true;
public bool Gamma
{
get
{
return _gamma;
}
set
{
_gamma = value;
OnPropertyChanged("ControlA");
OnPropertyChanged("ControlB");
OnPropertyChanged("ControlC");
OnPropertyChanged("ControlD");
OnPropertyChanged("ControlE");
}
}
private bool _delta = true;
public bool Delta
{
get
{
return _delta;
}
set
{
_delta = value;
OnPropertyChanged("ControlA");
OnPropertyChanged("ControlB");
OnPropertyChanged("ControlC");
OnPropertyChanged("ControlD");
OnPropertyChanged("ControlE");
}
}
public Visibility ControlA
{
get
{
Visibility result = Visibility.Hidden;
if (Alpha && (Beta || Gamma))
{
result = Visibility.Visible;
}
return result;
}
}
public Visibility ControlB
{
get
{
Visibility result = Visibility.Hidden;
if (Delta)
{
result = Visibility.Visible;
}
return result;
}
}
private bool _controlC = false;
public bool ControlC
{
get
{
return Delta || Beta;
}
}
private bool _controlD = false;
public bool ControlD
{
get
{
return Gamma && Alpha && Delta;
}
}
private bool _controlE = false;
public bool ControlE
{
get
{
return Alpha || Gamma;
}
}
}
Voici le convertisseur:
public class BooleanVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if((value == null) || (!(value is bool)))
return Binding.DoNothing;
Visibility elementVisibility;
bool shouldCollapse = ((bool)value);
if(parameter != null)
{
try
{
bool inverse = System.Convert.ToBoolean(parameter);
if(inverse)
shouldCollapse = !shouldCollapse;
}
catch
{
}
}
elementVisibility = shouldCollapse ? Visibility.Collapsed : Visibility.Visible;
return elementVisibility;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Je pense que c'est une bonne approche –