Validation rules using value from another control

后端 未结 1 1167
伪装坚强ぢ
伪装坚强ぢ 2021-01-11 15:21

I\'m trying to do something that I previously assumed would be quite easy: use the value from one control in the validation rule of another. My application has a variety of

相关标签:
1条回答
  • 2021-01-11 16:00

    For any who might face this problem, it is far easier to implement IDataErrorInfo to validate errors in general, and to accomplish validation against other controls in some logical grouping. I encapsulated the relevant properties (start, end, min and max) in a single class, bound the controls to those properties, and then used the IDataErrorInfo interface for validation. Relevant code is below...

    XAML:

        <TextBox Name="textboxStart" Grid.Row="0" Text="{Binding Path=Start, ValidatesOnDataErrors=True}" Margin="5"/>
        <TextBox Name="textboxEnd" Grid.Row="1" Text="{Binding Path=End, ValidatesOnDataErrors=True}" Margin="5"/>
    </Grid>
    

    C#:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Runtime.CompilerServices;
    using System.ComponentModel;
    
    namespace WpfApplication1 {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window {
            public MainWindow () {
                InitializeComponent();
    
                Parameter testParameter = new Parameter(0, 10);
                testGrid.DataContext = testParameter;
            }
        }
    
        public class Parameter: INotifyPropertyChanged, IDataErrorInfo {
            private decimal _start, _end, _min, _max;
            public event PropertyChangedEventHandler PropertyChanged;
    
            public Parameter () { }
    
            public Parameter (decimal min, decimal max) {
                this.Min = min;
                this.Max = max;
            }
    
            public decimal Start {
                get { return _start; }
                set {
                    _start = value;
                    //RaisePropertyChanged for both Start and End, because one may need to be marked as invalid because of the other's current setting.
                    //e.g. Start > End, in which case both properties are now invalid according to the established conditions, but only the most recently changed property will be validated
                    RaisePropertyChanged();
                    RaisePropertyChanged("End");
                }
            }
    
            public decimal End {
                get { return _end; }
                set {
                    _end = value;
                    //RaisePropertyChanged for both Start and End, because one may need to be marked as invalid because of the other's current setting.
                    //e.g. Start > End, in which case both properties are now invalid according to the established conditions, but only the most recently changed property will be validated
                    RaisePropertyChanged();
                    RaisePropertyChanged("Start");
                }
            }
    
            public decimal Min {
                get { return _min; }
                set { _min = value; }
            }
    
            public decimal Max {
                get { return _max; }
                set { _max = value; }
            }
    
            private void RaisePropertyChanged ([CallerMemberName] string propertyName = "") {
                if (PropertyChanged != null) {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            public string Error {
                get { return string.Empty; }
            }
    
            public string this[string columnName] {
                get {
                    string result = string.Empty;
    
                    switch (columnName) {
                        case "Start":
                            if (Start < Min || Start > Max || Start > End) {
                                result = "Out of range. Enter a value in the range: " + Min + " - " + End + ".";
                            }
                            break;
                        case "End":
                            if (End < Min || End > Max || End < Start) {
                                result = "Out of range. Enter a value in the range: " + Start + " - " + Max + ".";
                            }
                            break;
                    };
    
                    return result;
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题