【发布时间】:2021-05-17 14:09:32
【问题描述】:
我想了解一些有关仅在匹配特定条件时触发 wpf 事件的可能性的信息。
我稍微解释一下我的情况。
-
我有 4 个文本框必须满足 ValidationRule(例如 0 到 100 之间的十进制值),如果满足此条件,将触发 KeyDown 事件。
-
我也可以让它被触发的唯一键是回车键吗?这样我就不用在事件代码中检查了
无法提供代码,因为我不知道它是否可能。 任何帮助表示赞赏。
编辑:
嗨,我又回来了。这是窗户
<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;
}
}
【问题讨论】: