Sto provando a fare qualcosa che in precedenza avrei assunto sarebbe stato abbastanza semplice: utilizzare il valore di un controllo nella regola di convalida di un altro. La mia applicazione ha una varietà di parametri che l'utente può inserire, i parametri specifici in questione qui definiscono i punti di inizio e fine di un intervallo e l'utente imposta i valori attraverso una casella di testo.Regole di convalida che utilizzano il valore di un altro controllo
I due controlli in questione sono le iniziali e finali caselle di testo, e le seguenti condizioni devono essere controllate in validazione:
- Valore iniziale deve essere maggiore o uguale a un valore arbitrario
- valore finale deve essere minore o uguale a un valore arbitrario
- valore iniziale deve essere minore o uguale al valore terminare
Le prime due condizioni ho già accompl mentata. Il terzo è molto più difficile da implementare, perché non posso accedere al valore della casella di testo finale dal validatore. Anche se potessi, ci sono cinque diversi intervalli (ciascuno con la propria casella di testo iniziale e finale) che sto provando a convalidare, e ci deve essere una soluzione più elegante della creazione di una regola di convalida per ognuno.
ecco il codice XAML rilevanti:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:validators="clr-namespace:CustomValidators"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Name="textboxStart" Grid.Row="0">
<TextBox.Text>
<Binding Path="Start" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:MeasurementRangeRule Min="1513" Max="1583"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBox Name="textboxEnd" Grid.Row="1">
<TextBox.Text>
<Binding Path="End" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validators:MeasurementRangeRule Min="1513" Max="1583"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
Ed ecco il relativo codice 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;
using System.Globalization;
namespace WpfApplication1 {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private decimal _start;
private decimal _end;
public event PropertyChangedEventHandler PropertyChanged;
public decimal Start {
get { return _start; }
set {
_start = value;
RaisePropertyChanged();
}
}
public decimal End {
get { return _end; }
set {
_end = value;
RaisePropertyChanged();
}
}
private void RaisePropertyChanged ([CallerMemberName] string propertyName = "") {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
namespace CustomValidators {
public class MeasurementRangeRule : ValidationRule {
private decimal _min;
private decimal _max;
public decimal Min {
get { return _min; }
set { _min = value; }
}
public decimal Max {
get { return _max; }
set { _max = value; }
}
public override ValidationResult Validate (object value, CultureInfo cultureInfo) {
decimal measurementParameter = 0;
try {
if (((string) value).Length > 0)
measurementParameter = Decimal.Parse((String) value);
} catch (Exception e) {
return new ValidationResult(false, "Illegal characters or " + e.Message);
}
if ((measurementParameter < Min) || (measurementParameter > Max)) {
return new ValidationResult(false,
"Out of range. Enter a parameter in the range: " + Min + " - " + Max + ".");
} else {
return new ValidationResult(true, null);
}
}
}
}
La questione legata here sembra essere rilevante, ma non riesco a capire le risposte fornite.
Grazie ...
Hai guardato IDataErrorInfo o un BindingGroup? – Shoe
@Jim Ho guardato IDataErrorInfo, ristrutturato il mio codice per incapsulare le proprietà rilevanti (inizio, fine, min e max) nella loro stessa classe, e quindi implementato IDataErrorInfo. Quella configurazione ha funzionato come un fascino, molto apprezzato per il puntatore. Domani pubblicherò la risposta. –