【问题标题】:C# WPF Conditional event firingC# WPF 条件事件触发
【发布时间】:2021-05-17 14:09:32
【问题描述】:

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

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

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

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

无法提供代码,因为我不知道它是否可能。 任何帮助表示赞赏。

编辑:

嗨,我又回来了。这是窗户

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

这是主窗口类

    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 MainWindowViewModel
    {
        public TextBoxViewModels<double> TextBox { get; } = new TextBoxViewModels<double>();
    }

这是 TextBoxViewModel 类

    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 类

    public class BaseViewModel: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

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

这是 ValueConverter 类

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

这是 ValidationRule 类

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

【问题讨论】:

    标签: c# wpf events


    【解决方案1】:

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

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

    如果您指的是内置的 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)...
            }
            ...
        }
    }
    

    【讨论】:

    • 是的,我指的是 WPF 控件的内置事件,所以我必须检查处理程序中的按下键,我是否可以从代码中访问 ValidationResult?知道文本框何时有有效文本会派上用场
    • 您在哪里以及如何处理事件?这与任何验证规则有什么关系?
    • 我用我所有的代码发布了一个答案,你能帮我吗
    • 为什么在处理KeyDown 事件时还需要ValidationRule?不必要的部分似乎是ValidationRule。从事件处理程序调用您的验证逻辑?
    • '因为UI有一个Validation,而我的Text属性绑定了一个值转换器,所以我想知道用户在文本框中按Enter的时候,值实际上是有效的,因为我无法阻止用户使用无效文本按 Enter,我需要输入的确切值。需要验证规则,因此我不必从代码通知错误
    猜你喜欢
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多