C# WPF 条件事件触发

C# WPF Conditional event firing

我想了解一些有关仅在满足特定条件时才触发 wpf 事件的可能性的信息。

我稍微解释一下我的情况。

  1. 我有 4 个文本框必须满足 ValidationRule(示例是 0 到 100 之间的十进制值),如果满足此条件,则将触发 KeyDown 事件。

  2. 我是否也可以让它被触发的唯一键是回车键?这样我就不必在事件代码中检查它了

无法提供代码,因为我不知道这是否可行。 感谢任何帮助。

编辑:

嗨,我又回来了。这是 window

    <Window.Resources>
        <Style x:Key="TextBoxInError" TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                    <Setter Property="ToolTipService.InitialShowDelay" Value="1"/>
                </Trigger>
            </Style.Triggers>
        </Style>
        <vc:StringToDoubleConverter Format="N2" x:Key="stringToDoubleConverter"/>
    </Window.Resources>
    <StackPanel>
        <TextBox  Width="100" Margin="10" KeyDown="TextBox_KeyDown" Style="{StaticResource TextBoxInError}">
            <TextBox.Text>
                <Binding Path="TextBox.Value" Converter="{StaticResource stringToDoubleConverter}" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <vr:RegexValidationRule Rule="^\d+,?\d{0,2}$" ErrorMessage="Can have up to 2 decimal digit"/>
                        <vr:DoubleRangeValidationRule Min="0" Max="100"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    </StackPanel>

这是主要的windowclass

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            
            InitializeComponent();
            this.DataContext = ViewModel;
        }

        MainWindowViewModel ViewModel = new MainWindowViewModel();

        private void TextBox_KeyDown(object sender, KeyEventArgs e)
        {
            //How can I acces the ValidationResult from here? Since evaluating it again is unneccessary work
            if (e.Key = Key.Enter /*&& Check validation result*/) 
            {
                //Do something
            }
        }
    }

这是 MainWindowViewModel class

    class MainWindowViewModel
    {
        public TextBoxViewModels<double> TextBox { get; } = new TextBoxViewModels<double>();
    }

这是 TextBoxViewModel class

    public class TextBoxViewModels<T> : BaseViewModel
    {
        public T Value
        {
            get
            {
                return _Value;
            }
            set
            {
                if (!_Value.Equals(value))
                {
                    _Value = value;
                    RaisePropertyChanged(nameof(Value));
                }
            }
        }

        public bool IsEnabled
        {
            get
            {
                return _IsEnabled;
            }
            set
            {
                if (_IsEnabled != value)
                {
                    _IsEnabled = value;
                    RaisePropertyChanged(nameof(IsEnabled));
                }
            }
        }
        public bool IsVisible
        {
            get
            {
                return _IsVisible;
            }
            set
            {
                if (_IsVisible != value)
                {
                    _IsVisible = value;
                    RaisePropertyChanged(nameof(IsVisible));
                }
            }
        }

        private T _Value;
        private bool _IsEnabled;
        private bool _IsVisible;
    }

这是 BaseViewModel class

    public class BaseViewModel: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

这是值转换器class

    public class StringToDoubleConverter : IValueConverter
    {
        public string Format { get; set; } = "";
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is double)
            {
                return Format != String.Empty ? ((double)value).ToString(Format) : ((double)value).ToString();
            }
            return "";
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                return Double.Parse((string)value);
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
    }

这是验证规则class

    public class DoubleRangeValidationRule : ValidationRule
    {
        public double Min { get; set; } = Double.MinValue;
        public double Max { get; set; } = Double.MaxValue;
        public bool IncludeExtremes { get; set; } = true;
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            double number = 0;
            try
            {
                if (((string)value).Length > 0)
                {
                    number = Double.Parse((string)value);
                }
            }
            catch (Exception ex)
            {
                return new ValidationResult(false, $"Illegal characters or {ex.Message}");
            }
            if (IncludeExtremes)
            {
                if (number < Min || number > Max)
                {
                    return new ValidationResult(false, $"Please enter a value in the range: {Min} - {Max}, including extremes");
                }
            }
            else
            {
                if (number <= Min || number >= Max)
                {
                    return new ValidationResult(false, $"Please enter a value in the range: {Min} - {Max}, excluding extremes");
                }
            }
            return ValidationResult.ValidResult;
        }
    }

您显然需要在某处定义和评估条件。

您可以在事件处理程序中执行此操作,也可以在引发事件之前执行此操作,前提是您可以控制实际引发事件的代码。

如果您指的是内置 KeyDown 事件,则您无法控制何时引发此事件,因此您应该在处理程序中检查您的条件。

编辑:

您可以使用 Validation.GetErrors 方法检查事件处理程序中是否存在任何验证错误:

private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        if (Validation.GetErrors((TextBox)sender).Count > 0)
        {
            //has validation error(s)...
        }
        ...
    }
}