61 messaggi dal 20 maggio 2009
Salve,
ho un applicazione strutturata secondo l'architettura MVVM.
questo è il viewModel base che implementa INoifyPropertyChanged:
public class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;


        public BaseViewModel()
        {
        }

        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }



Dato un oggetto:
 public class persona
 {
   public string nome{get;set;}
   public ObservableCollection<figli> Figli{get;set;}
 }


Nel ViewModel ho una variabile di tipo Persona(pers), inizializzata nel costruttore del viewmodel.

Nell'interfaccia utente, il nome è bindato in questo modo.
<textblock text={binding pers.nome}/>

La lista dei figli è bindata in questo modo:
<ItemsControl Width="70" Margin="5,20,0,0" ItemsSource="{Binding pers.figli}">

il binding iniziale funziona correttamente.

poi premendo un pulsante parte un algoritmo che va a modificare l'elenco dei figli.
pers.figli[2].Età = 20;
RaisePropertyChanged("pers.figli");

in questo modo nel momento che l'algoritmo cambia l'età di un figlio la modifica si dovrebbe vedere nell'interfaccia utente, invece non avviene.

mi chiedo se RaisePropertyChanged deve avere il nome di una proprietà singola e non accetti costrutti tipo <oggetto>.<proprietà>

anche eseguendo un RaisePropertyChanged("pers") non avviene l'aggioramento.

Il nome invece viene aggiornato correttamente.

Vivaldi Francesco
Ciao, il problema è che non hai implementato INotifyPropertyChanged su persona, quindi non viene notificato il change dell'elemento

MCTS: Silverlight 4, Development
61 messaggi dal 20 maggio 2009
é vero però eseguendo la riga
RaisePropertyChanged("pers.figli"); forzo l'aggiornamento.

Molte operazioni vengono fatte tramite un backgroundWorker, quindi non posso implementare INotifyPropertyChanged direttamente sulle entità perché in caso di modifica il thread secondario tenterebbe di aggiornare l'interfaccia causando un eccezione.

Quindi l'aggiramento viene fatto col worker.ReportProgress, e nell'evento associato con RaisePropertyChanged("pers.figli");

In ogni caso anche implementando INotifyPropertyChanged nelle entità e non usando backgroundWorker la cosa non cambia.

é necessario creare una proprietà "FigliPerson" che ritorna pers.figli
e implementa INotifyPropertyChanged.

RaisePropertyChanged("pers.figli") //Non aggiorna
RaisePropertyChanged("FigliPersona") //Aggiorna

il binding in lettura nello xaml invece supporta anche sintassi di tipo oggetto.proprietà.

Vivaldi Francesco
41 messaggi dal 14 ottobre 2010
artanis ha scritto:
é vero però eseguendo la riga
RaisePropertyChanged("pers.figli"); forzo l'aggiornamento.

Molte operazioni vengono fatte tramite un backgroundWorker, quindi non posso implementare INotifyPropertyChanged direttamente sulle entità perché in caso di modifica il thread secondario tenterebbe di aggiornare l'interfaccia causando un eccezione.

Quindi l'aggiramento viene fatto col worker.ReportProgress, e nell'evento associato con RaisePropertyChanged("pers.figli");

In ogni caso anche implementando INotifyPropertyChanged nelle entità e non usando backgroundWorker la cosa non cambia.

é necessario creare una proprietà "FigliPerson" che ritorna pers.figli
e implementa INotifyPropertyChanged.

RaisePropertyChanged("pers.figli") //Non aggiorna
RaisePropertyChanged("FigliPersona") //Aggiorna

il binding in lettura nello xaml invece supporta anche sintassi di tipo oggetto.proprietà.


Ciao,
quel che è certo è che il parametro di RaisePropertyChanged deve essere il nome di una proprietà
Modificato da antonio.pelleriti il 27 settembre 2011 15.09 -

Il libro su Silverlight in italiano:
Silverlight 4 - Guida Alla Programmazione
61 messaggi dal 20 maggio 2009
ma la proprietà deve essere dichiarata nel viewModel ? oppure può anche essere dichiarata all'interno di un ogggeto ?.

figli è un proprietà, ma non è dichiarata nel viewmodel ma all'interno dell'oggetto _pers.

l'oggetto _pers e dichiarato nel viewmodel e ha un proprietà pubblica pers.

Il binding pers.figli funziona bene,
ma il raisePropertyChanged("pers.figli") non funziona.

Vivaldi Francesco
41 messaggi dal 14 ottobre 2010
a RaisePropertyChanged devi passare il nome di una proprietà.
L'interfaccia INotifyPropertyChanged viene utilizzata per notificare che il valore di una proprietà è cambiato, quindi deve essere implementata dalla classe che rappresenta la tua entità, per esempio da Figlio.

Quindi se modifichi l'età di un figlio, devi notificare che è cambiata la proprietà Età:
public string Eta
{
        get { return eta; }
        set
        {
            eta=value;
            NotifyPropertyChanged("Eta");
        }
}

Modificato da antonio.pelleriti il 06 ottobre 2011 08.55 -

Il libro su Silverlight in italiano:
Silverlight 4 - Guida Alla Programmazione
61 messaggi dal 20 maggio 2009
Ma implementandolo nell'entità direttamente, la notifica di aggiornamento avviene nel momento in cui il valore cambia, e questo avviene in un'altro thread, ed essendo la properietà bindata bidirezionale all'interfaccia genera un errore in quanto il thread secondario tenta di aggiornare l'interfaccia utente.

Vivaldi Francesco
Usa il dispatchervdel thread ui per sincronizzarti prima di impostare la property

MCTS: Silverlight 4, Development

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.