C# WPF 条件事件触发
C# WPF Conditional event firing
我想了解一些有关仅在满足特定条件时才触发 wpf 事件的可能性的信息。
我稍微解释一下我的情况。
我有 4 个文本框必须满足 ValidationRule(示例是 0 到 100 之间的十进制值),如果满足此条件,则将触发 KeyDown 事件。
我是否也可以让它被触发的唯一键是回车键?这样我就不必在事件代码中检查它了
无法提供代码,因为我不知道这是否可行。
感谢任何帮助。
编辑:
嗨,我又回来了。这是 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)...
}
...
}
}
我想了解一些有关仅在满足特定条件时才触发 wpf 事件的可能性的信息。
我稍微解释一下我的情况。
我有 4 个文本框必须满足 ValidationRule(示例是 0 到 100 之间的十进制值),如果满足此条件,则将触发 KeyDown 事件。
我是否也可以让它被触发的唯一键是回车键?这样我就不必在事件代码中检查它了
无法提供代码,因为我不知道这是否可行。 感谢任何帮助。
编辑:
嗨,我又回来了。这是 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)...
}
...
}
}