2013-03-02 12 views
5

Va bene, questo è in qualche modo legati a questa domanda: WPF Printing multiple pages from a single View ModelMVVM + UserControl + proprietà di dipendenza

ho cercato di seguire i consigli forniti lì, ma ora mi sono bloccato.

La mia applicazione utilizza un MainView.xaml e il MainViewViewModel.cs appropriato, sto usando MVVM Light in background.

ora - secondo il post - sembra che devo fare la seguente:

  • Creare un controllo utente
  • espongono alcune proprietà dal controllo dell'utente
  • Assicurarsi che il modello di visualizzazione mostra questi immobili

L'idea è chiara ma sono bloccato quando cerco di notificarci a vicenda.

mio controllo utente (UcTest.xaml) espone una proprietà di dipendenza:

public string SpecialText 
{ 
    get { return (string)GetValue(SpecialTextProperty); } 
    set 
    { 
     SetValue(SpecialTextProperty, value); 

    } 
} 

// Using a DependencyProperty as the backing store for SpecialText. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty SpecialTextProperty = 
    DependencyProperty.Register("SpecialText", typeof(string), typeof(UcTest), new PropertyMetadata(new PropertyChangedCallback(SpecialTextChangedPropertyCallback))); 

private static void SpecialTextChangedPropertyCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
{ 
    // Do something 
    Debug.WriteLine("Ffgdgf"); 
} 

Va bene, così io ora hanno un controllo utente che ha alcune proprietà di dipendenza. Tuttavia, queste proprietà sono completamente separate dalle mie proprietà ViewModel (quelle sono quelle che devono essere visualizzate).

Quindi, in pratica ho due possibilità:

  • Come posso ora dire al mio ViewModel per l'UserControl che alcune proprietà sono cambiati?
  • Esiste la possibilità di dimenticare le proprietà di dipendenza e accedere direttamente al modello di visualizzazione?

informazioni aggiuntive # 1: ho caricato un (semplice) esempio di quello che sto cercando di fare qui: Example Project. Vorrei modificare il valore dell'etichetta in UserControl1 (tramite la proprietà di associazione nel ViewModel per UserControl1) dal mio MainViewViewModel.

+0

Utilizzare il binding di dati –

+1

Ciò significherebbe che il mio UserControl dovrebbe implementare INotifyPropertyChanged che è sostanzialmente ciò che dovrebbe fare il mio ViewModel. –

risposta

4

OK, dopo ore di googling sembra che l'approccio "corretto" a questo non è affatto farlo. L'approccio generale è quello di mantenere i dati nel MainViewModel e non utilizzare un ViewModel aggiuntivo per UserControl (che trovo un po '... beh .. non così buono). Il problema principale è che non esiste un meccanismo semplice per ottenere i dati dalla proprietà delle dipendenze a ViewModel.

Per la stampa, ora sono tornato a farlo esclusivamente in codice.

+0

Questo può essere applicato ai casi in cui si separano gli elementi della scheda nei controlli utente. Ma per quanto riguarda i controlli generali, come un browser di file, che vengono visualizzati più volte? – bytecode77

+0

@Tom L. nella tua situazione, il meglio che ho potuto ottenere è di non impostare un contesto dati nel controllo utente, quindi su caricamento di Windows salvare le proprietà passate dal DP alle variabili, quindi impostare il contesto su una nuova istanza della tua VM. Quindi imposta le proprietà appropriate nella VM e continua. Non è l'ideale, ma ha fatto il lavoro. Vorrei che nei metadati del DP potessi specificare in quale contesto ottenere i binding. –

5

Di norma, la proprietà di UserControl alla proprietà ViewModel è bind. Una rilegatura bidirezionale funzionerebbe in entrambe le direzioni, da ViewModel a View e viceversa.

<Window x:Class="TestApplication.MainWindow" ...> 
    <Window.DataContext> 
     <local:MyViewModel/> 
    </Window.DataContext> 
    <Grid> 
     <local:UcTest SpecialText="{Binding MyViewModelProperty, Mode=TwoWay}"/> 
    </Grid> 
</Window> 

per accedere direttamente l'oggetto ViewModel nell'esempio di cui sopra, si potrebbe semplicemente lanciare la proprietà del UserControl DataContext al tipo ViewModel. DataContext è ereditato da MainWindow.

var viewModel = DataContext as MyViewModel; 
var property = viewModel.MyViewModelProperty; 

Si potrebbe naturalmente anche assegnare direttamente un'istanza specializzata ViewModel al DataContext del UserControl:

<local:UcTest SpecialText="{Binding MyViewModelProperty, Mode=TwoWay}"/> 
    <local:UcTest.DataContext> 
     <local:UserControlViewModel/> 
    </local:UcTest.DataContext> 
</local:UcTest> 

oppure si può creare l'istanza ViewModel come una risorsa in un dizionario risorse e assegnare il DataContext come questo

<local:UcTest DataContext="{StaticResource MyUserControlViewModel}" 
       SpecialText="{Binding MyViewModelProperty, Mode=TwoWay}"/> 
+0

Hm, penso che potrei fraintendermi. Il problema è che UserControl ha il proprio ViewModel a cui vorrei collegarmi. O pensi che sarebbe meglio mantenere le proprietà nel MainViewModel e utilizzare semplicemente UserControl senza il proprio ViewModel? –

+0

Dipende dal design dell'applicazione. Entrambi sono una soluzione valida. Si potrebbe anche assegnare direttamente la proprietà DataContext di UserControl. – Clemens

+1

Hm, no ... non lo capisco davvero. Ti dispiacerebbe postare un esempio? Perché non appena si modifica DataContext per UserControl a UserControlViewModel non è possibile assegnare altre variabili poiché UserControl non è al corrente di queste proprietà. Come posso assegnare qualcosa a "SpecialText" se SpecialText non è DependencyProperty? –

Problemi correlati