【问题标题】:Disable/Enable Button based on WPF DatePicker Validation using MVVM基于 WPF DatePicker 验证使用 MVVM 禁用/启用按钮
【发布时间】:2013-07-03 06:31:44
【问题描述】:

我有一个使用 IDataErrorInfo 接口处理验证的 ViewModel。这适用于组合框、文本框、复选框等。

DatePicker 似乎根据绑定到“DateTime?”来验证输入本身。 ViewModel 中的属性也可以正常工作。

现在我想在 ViewModel 中使用命令绑定禁用/启用按钮。 如果任何控件显示验证错误,则应禁用该按钮。

使用 MVVM-Light 的 RelayCommand 我得到了这个工作除了 DatePickers 之外的任何东西,因为他们验证自己。

中继命令代码:

this.DoSomethingCommand = new RelayCommand(this.DoSomething, this.CanDoSomething);


有没有办法让他们的 Validation-State 进入 ViewModel?
我真的很感谢这方面的一些帮助!



在任何人提到它之前:我已经尝试使用 Multidatatrigger 并因此处理视图中的按钮 IsEnabled 属性。它没有用,IsEnabled 是我无法使用数据触发器更改的唯一属性。即使没有任何 CommandBindings。(可能是因为我的公司 Authentication-Framework)

这是我尝试的 DataTrigger 代码:

    <Button x:Uid="Button_1"
            Content="DoSomething"
            IsDefault="True"
            Command="{Binding DoSomethingCommand}">

        <Button.Style>
            <Style x:Uid="Style_1"
                   TargetType="{x:Type Button}"
                   BasedOn="{StaticResource {x:Type Button}}">
                <Setter x:Uid="Setter_2"
                        Property="IsEnabled"
                        Value="false" />
                <Style.Triggers>
                    <MultiDataTrigger x:Uid="MultiDataTrigger_1">
                        <MultiDataTrigger.Conditions>
                            <Condition x:Uid="Condition_1"
                                       Binding="{Binding (Validation.HasError), ElementName=ComboBox1}"
                                       Value="false" />
                            <Condition x:Uid="Condition_2"
                                       Binding="{Binding (Validation.HasError), ElementName=ComboBox2"
                                       Value="false" />
                            <Condition x:Uid="Condition_3"
                                       Binding="{Binding (Validation.HasError), ElementName=ComboBox3}"
                                       Value="false" />
                            <Condition x:Uid="Condition_4"
                                       Binding="{Binding (Validation.HasError), ElementName=ComboBox4}"
                                       Value="false" />
                            <Condition x:Uid="Condition_5"
                                       Binding="{Binding (Validation.HasError), ElementName=ComboBox5}"
                                       Value="false" />
                            <Condition x:Uid="Condition_6"
                                       Binding="{Binding (Validation.HasError), ElementName=DatePicker1}"
                                       Value="false" />
                            <Condition x:Uid="Condition_7"
                                       Binding="{Binding (Validation.HasError), ElementName=DatePicker2}"
                                       Value="false" />
                        </MultiDataTrigger.Conditions>
                        <Setter x:Uid="Setter_1"
                                Property="IsEnabled"
                                Value="True" />
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

【问题讨论】:

  • 嗨@M C- 在您的MultiDataTrigger 中,尝试使用&lt;Condition Binding="{Binding ElementName=txtTextBox, Path=(Validation.HasError)}" Value="false"/&gt; 并查看是否可行。希望这可以帮助。 :)
  • 试过了。没用。正如我所说:它适用于除按钮的 IsEnabled 属性之外的任何内容。例如,我可以使用此数据触发器更改背景颜色。
  • 请尝试下面的代码@MC

标签: wpf validation data-binding datepicker multidatatrigger


【解决方案1】:

请试试这个: 在 Xaml 中:

  <Grid> 
    <Button IsDefault="True" Content="Login" Height="27" Width="75" CommandParameter="{Binding ElementName=XXXXXXXX}" Command="{Binding LoginCommand, Source={StaticResource LoginController}}" Grid.Column="1" Grid.Row="7"/>

    <Button Content="Cancel" Height="27" Width="75" Grid.Column="3" Grid.Row="7" IsCancel="True">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <i:InvokeCommandAction Command="{Binding CancelCommand,Source={StaticResource LoginController}}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>
    <Label Foreground="White" Content="User Name:" Grid.Column="1" Grid.Row="1"/>
    <Label Foreground="White" Content="Password:" Grid.Column="1" Grid.Row="3"/>
    <TextBox x:Name="UserName" HorizontalAlignment="Left" Width="130" Height="27" Grid.Column="3" Grid.Row="1" Text="{Binding UserName, Source={StaticResource LoginController}, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=true, NotifyOnValidationError=true}"/>
    <PasswordBox HorizontalAlignment="Left" Width="130" Height="27" w:PasswordHelper.Attach="True" 
     w:PasswordHelper.Password="{Binding Password,Source={StaticResource LoginController}, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=true, NotifyOnValidationError=true}" Grid.Column="3" Grid.Row="3" />        
</Grid>

在 ViewModel 中:

     public ICommand LoginCommand
    {
        get
        {
            return new RelayCommand(OnLogin, IsEnable);
        }
    }
 public void OnLogin(object param)
    {
        //code
    }
bool IsEnable(object obj)
    {
           //Code for you button enable for example "return false;"
    }

希望这会对你有所帮助。

【讨论】:

    【解决方案2】:

    最终解决方案:

    我使用以下代码使其按要求工作:

    查看:

        <Button x:Uid="Button_1"
                Content="DoSomething"
                IsDefault="True"
                Command="{Binding DoSomethingCommand}">
            <Button.CommandParameter>
                <MultiBinding x:Uid="MultiBinding_1" Converter="{StaticResource validationConverter}">
                    <Binding x:Uid="Binding_1" ElementName="ComboBox1"
                             Path="(Validation.HasError)" />
                    <Binding x:Uid="Binding_2" ElementName="ComboBox2"
                             Path="(Validation.HasError)" />
                    <Binding x:Uid="Binding_3" ElementName="ComboBox3"
                             Path="(Validation.HasError)" />
                    <Binding x:Uid="Binding_4" ElementName="ComboBox4"
                             Path="(Validation.HasError)" />
                    <Binding x:Uid="Binding_5" ElementName="ComboBox5"
                             Path="(Validation.HasError)" />
                    <Binding x:Uid="Binding_6" ElementName="DatePicker1"
                             Path="(Validation.HasError)" />
                    <Binding x:Uid="Binding_7" ElementName="DatePicker2"
                             Path="(Validation.HasError)" />
                </MultiBinding>
            </Button.CommandParameter>                
        </Button>
    

    验证转换器:

    public class ValidationConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            foreach (var item in values)
            {
                if ((bool)item == true)
                {
                    return true;
                }
            }
    
            return false;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            List<object> list = new List<object>();
    
            foreach (var item in targetTypes)
            {
                list.Add(Binding.DoNothing);
            }
    
            return list.ToArray();
        }
    }
    

    ViewModel 中的 CanExecute 方法:

    private bool CanDoSomething(object obj)
    {
        return !(bool)obj;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      • 1970-01-01
      • 1970-01-01
      • 2013-11-23
      相关资源
      最近更新 更多