gpt4 book ai didi

.net - WPF - 使用 MVVM 根据模型的不同状态禁用和启用不同控件的优雅方式

转载 作者:行者123 更新时间:2023-12-04 14:35:24 24 4
gpt4 key购买 nike

我正在为以下问题寻找一个优雅的解决方案。

假设我们有一个 (View)Model 具有以下 bool 属性:

  • 阿尔法
  • 测试版
  • Gamma
  • 达美

  • 接下来,我在表面上有 5 个控件,这些控件仅在满足基于这些属性的条件时才可见。当然,一旦这些属性之一更新,更改应该立即传播:
  • ControlA -> Alpha && ( Beta || Gamma )
  • ControlB -> 三角洲
  • ControlC -> 三角洲 ||测试版
  • ControlD -> Gamma && Alpha && Delta
  • ControlE -> 阿尔法 || Gamma

  • 到目前为止,我想出的唯一解决方案是使用 MultiValueConverters。

    ControlA 的示例:
    <ControlA>
    <ControlA.Visibility>
    <MultiBinding Converter={StaticResource ControlAVisibilityConverter}>
    <Binding Path="Alpha"/>
    <Binding Path="Beta"/>
    <Binding Path="Gamma"/>
    </MultiBinding>
    </ControlA.Visibility>
    </ControlA>

    此 ControlAVIsibilityConverter 检查条件“Alpha && (Beta || Gamma)”并返回适当的值。

    它确实有效......好吧......但也许你可以想出一个更优雅的解决方案?

    谢谢,
    双习惯

    最佳答案

    在这种情况下,为每个规则编写一个转换器会将您的业务逻辑放在两个位置(在转换器和 View 模型中)。
    我建议使用 INotifyPropertyChanged 事件为 ViewModel 中的每个控件创建一个属性/标志,以决定该控件是否可见(或其他行为)。

    请注意,当您查看我的 View 模型(如下)时,您会看到我公开了 bool 和 Visibilty 类型的属性。

    如果您需要将该属性用作一般规则,请使用 bool 和 DataTrigger。

    public bool ControlD

    如果您只需要控制可见性,您可以直接绑定(bind)到可见性:
    public Visibility ControlA

    更新 :
    由于@Wallstreet Programmer 的评论,我添加了另一个选项来使用 BooleanVisibilityConverter。我更新了下面的第五个控件以反射(reflect)如何使用转换器。我在底部添加了转换器的代码。

    这是 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>

    这是 View 模型:
    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;
    }
    }
    }

    这是转换器:
    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();
    }
    }

    关于.net - WPF - 使用 MVVM 根据模型的不同状态禁用和启用不同控件的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3764484/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com