C#WPF或ValidationRules之间的逻辑门

时间:2016-01-04 08:43:12

标签: c# wpf multidatatrigger

我正在使用带有验证的组合框和一个保存按钮,如下所示:

<ComboBox   ItemsSource="{Binding ...}" 
            x:Name="cmbGenerationTariff" IsEnabled="False" >
    <ComboBox.SelectedItem>
        <Binding Path="..." UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
            <Binding.ValidationRules>
                <common:ValidationRuleStringAnyLength  ValidatesOnTargetUpdated="True"/>
            </Binding.ValidationRules>
        </Binding>
    </ComboBox.SelectedItem>
</ComboBox>

...

<Button x:Name="btnSaveSite" Click="btnSave_Click"  Content="SAVE">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="IsEnabled" Value="false" />
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>                           
                        <Condition Binding="{Binding ElementName=cmbGenerationTariff, Path=(Validation.HasError)}" Value="false" />
                        <Condition Binding="{Binding ElementName=cmbTimeZone, Path=(Validation.HasError)}" Value="false" />                         
                        <Condition Binding="{Binding ElementName=txtCity, Path=(Validation.HasError)}" Value="false" />
                        <Condition Binding="{Binding ElementName=cmbCountry, Path=(Validation.HasError)}" Value="false" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="IsEnabled" Value="true" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

它运作得很好。如果所有元素都有效,则启用保存按钮。

我想要的是在禁用元素时启用保存按钮(换句话说,我不需要验证禁用元素的值)。

我该怎么办?我可以使用'OR'条件(元素是否有效OR元素被禁用)?

2 个答案:

答案 0 :(得分:4)

正如@Adi Lester所说,你最好在这里使用MVVM pattern 考虑添加例如MVVMLight作为依赖,通过NuGet,使开始更容易。

如果你这样做,你将更好地控制你的逻辑。考虑简单的窗口XAML

<Window.DataContext>
    <local:MainViewModel />
</Window.DataContext>
<StackPanel>
    <!--Bind to Text and IsEnabled properties in ViewModel-->
    <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" 
             IsEnabled="{Binding IsEnabled}">
    </TextBox>
    <!--Bind to IsEnabled property in ViewModel-->
    <CheckBox Content="Text input enabled" 
              IsChecked="{Binding IsEnabled}">
    </CheckBox>
    <!--Bind to SaveCommand in ViewModel-->
    <Button Content="Save" 
            Command="{Binding SaveCommand}">
    </Button>
</StackPanel>

MainWindow代码隐藏保持原样,MainViewModel(DataContext)

public class MainViewModel : ViewModelBase // <- MVVMLight ViewModel base class
{
    private string _text = null;
    private bool _isEnabled = true;

    public MainViewModel()
    {
        SaveCommand = new RelayCommand(
            // Execute command
            () => Console.WriteLine(@"Save command received, input value:{0}", Text),
            // Can execute command?
            () => !IsEnabled || (IsEnabled && !string.IsNullOrWhiteSpace(Text)));
    }

    public ICommand SaveCommand { get; set; }

    public string Text
    {
        get { return _text; }
        set { _text = value; RaisePropertyChanged(); }
    }

    public bool IsEnabled
    {
        get { return _isEnabled; }
        set { _isEnabled = value; RaisePropertyChanged(); }
    }
}

Tadah!现在,当输入文本或未选中复选框时,您可以使用逻辑切换Save按钮on。作为额外奖励,您现在正式正确行事;)

enter image description here

答案 1 :(得分:2)

看起来你不是在使用MVVM,但正确的做法是为你的按钮使用一个命令,并在你的viewmodel中使用CanExecute逻辑。在那里,您应该能够访问数据的状态并执行更复杂的验证逻辑。