Se si sta utilizzando MVVM veramente quindi il pulsante OK scatto deve essere gestita da qualche Command
. Questo comando deve provenire dal tuo ViewModel
. Le proprietà associate a Expliticly
devono provenire nuovamente dal tuo ViewModel
. Quindi, cosa ti sta fermando.
- Non utilizzare
Explicit
vincolante, ma usano OneWay
vincolante.
- In te pulsante, legare un comando e associare un parametro di comando alla proprietà
OneWay
dipendenza legato.
- Nel gestore Execute del comando (che deve essere un metodo del ViewModel), modificare la proprietà ViewModel con il parametro in arrivo.
- Sollevare il
NotifyPropertyChanged
per quella proprietà dal ViewModel
.
Ad es
Si supponga che ho bisogno di aggiornare il testo di una TextBox nuovamente dentro il mio modello sul pulsante OK click.
Quindi per quello ho una classe EmployeeViewModel
che contiene la proprietà EmployeeName
. La proprietà è ha un getter e un setter. Il setter solleva la notifica modificata della proprietà. Il modello di vista ha anche un'altra proprietà di tipo ICommand
denominata SaveNameCommand
che restituisce un comando da eseguire.
EmployeeViewModel
è il tipo di dati di contesto mio punto di vista. Myview ha un TextBox
(chiamato come x: Name = "EmployeeNameTxBx") OneWay
legato alla EmployeeName
e un pulsante come OK
. Leggo la proprietà Button.Command
alla proprietà EmployeeViewModel.SaveNameCommand
e Button.CommandParameter
è legata alla proprietà EmployeeNameTxBx.Text
.
<StackPanel>
<TextBox x:Name="EmployeeNameTxBx"
Text="{Binding EmployeeName, Mode=OneWay}" />
<Button Content="OK"
Command="{Binding SaveNameCommand}"
CommandParameter="{Bidning Text, ElementName=EmployeeNameTxBx}" />
</StackPanel>
Dentro il mio EmployeeViewModel
devo OnSaveNameCommandExecute(object param)
metodo per eseguire il mio SaveNameCommand
.
In questo eseguire questo codice ...
var text = (string)param;
this.EmployeeName = text;
questo modo solo tasto OK clic, aggiorna il testo del TextBox nuovamente dentro EmployeeName
proprietà del modello.
EDIT
Guardando i vostri commenti qui sotto, vedo che si sta cercando di implementare convalida su un'interfaccia utente. Ora questo cambia un po 'le cose.
IDataErrorInfo
e relativi lavori di convalida SOLO SE i controlli di input (ad esempio TextBox) sono TwoWay associato. Sì, questo è come è destinato. Quindi ora puoi chiedere "Questo significa che l'intero concetto di NON CONCEDERE che i dati non validi da passare al modello sono futili in MVVM se usiamo IDataErrorInfo"?
Non proprio!
Vedere MVVM non applica una regola che SOLO i dati validi dovrebbero tornare. Accetta dati non validi ed è così che funziona IDataErrorInfo
e vengono notificati gli errori. Il punto è che ViewModel è un semplice softcopy della visualizzazione in modo che possa essere sporco. Che cosa dovrebbe assicurarsi è che questa sporcizia non è impegnata per le interfacce esterne come servizi o database.
Tale flusso di dati non valido deve essere limitato dal ViewModel
testando i dati non validi. E quei dati arriveranno se avremo il binding TwoWay
abilitato. Quindi, considerando che stai implementando IDataErrorInfo
, devi avere i binding TwoWay
che sono perfettamente consentiti in MVVM.
Approccio 1:
Cosa succede se wan per validare in modo esplicito alcune voci sul interfaccia utente su pulsante di scatto?
Per questo utilizzare un trucco di convalida ritardata. Nel ViewModel viene visualizzato un flag chiamatoValidating. Impostalo come falso per impostazione predefinita.
nella vostra proprietà IDataErrorInfo.this
saltare la convalida controllando bandiera isValidating ...
string IDataErrorInfo.this[string columnName]
{
get
{
if (!isValidating) return string.Empty;
string result = string.Empty;
bool value = false;
if (columnName == "EmployeeName")
{
if (string.IsNullOrEmpty(AccountType))
{
result = "EmployeeName cannot be empty!";
value = true;
}
}
return result;
}
}
Poi nel comando OK eseguito gestore, controllare il nome del dipendente e poi alzare eventi di modifica di proprietà di notifica per la stessa proprietà ...
private void OnSaveNameCommandExecute(object param)
{
isValidating = true;
this.NotifyPropertyChanged("EmployeeName");
isValidating = false;
}
Questo attiva la convalida SOLO quando si fa clic su OK. Ricordare che lo EmployeeName
DEVE contenere dati non validi affinché la convalida funzioni.
Approccio 2:
Cosa succede se voglio aggiornare esplicitamente attacchi senza modalità TwoWay in MVVM?
Quindi sarà necessario utilizzare Attached Behavior
. Il comportamento si collegherà al pulsante OK e accetterà l'elenco di tutti gli elementi che necessitano di aggiornamento dei loro binding.
<Button Content="OK">
<local:SpecialBindingBehavior.DependentControls>
<MultiBinding Converter="{StaticResource ListMaker}">
<Binding ElementName="EmployeeNameTxBx" />
<Binding ElementName="EmployeeSalaryTxBx" />
....
<MultiBinding>
</local:SpecialBindingBehavior.DependentControls>
</Button>
Il ListMaker
è un IMultiValueConverter
che converte semplicemente in un elenco valori ...
Convert(object[] values, ...)
{
return values.ToList();
}
Nella tua SpecialBindingBehavior
hanno un DependentControls
proprietà modificata gestore ...
private static void OnDependentControlsChanged(
DependencyObject depObj,
DependencyPropertyChangedEventArgs e)
{
var button = sender as Button;
if (button != null && e.NewValue is IList)
{
button.Click
+= new RoutedEventHandler(
(object s, RoutedEventArgs args) =>
{
foreach(var element in (IList)e.NewValue)
{
var bndExp
= ((TextBox)element).GetBindingExpression(
((TextBox)element).Textproperty);
bndExp.UpdateSource();
}
});
}
}
Ma saranno ancora suggerire di usare la mia precedente MVVM puro basato ** Approccio 1.
primo grazie per la tua risposta dettagliata! e tornando al mio problema, sto usando mvvm puro e ho il comando in my vm e sto usando NotifyPropertyChanged. ma se io uso OneWay binding e ho nella casella 10 textbox il suo significato ho bisogno di inviare i parametri di comando 10 nomi di elementi? e quindi aggiornarli manualmente? non c'è modo di usare il binding di ToWay? – Maya
anche adesso sto usando IDataError per convalidare il testo nelle caselle di testo, se userò il binding OneWay posso ancora convalidare il testo? – Maya
@Maya si prega di vedere il mio naswer modificato sopra. –