1

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

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

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

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

中继命令代码:

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


有没有办法让他们的验证状态进入 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>
4

2 回答 2

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>

在视图模型中:

     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;"
    }

希望这会帮助你。

于 2013-07-05T11:15:27.967 回答
0

最终解决方案:

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

看法:

    <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;
}
于 2013-07-09T13:32:01.793 回答