none
UserControl con mvvm RRS feed

  • Domanda

  • ciao a tutti

    In un progetto WPF che usa mvvm, devo aggiungere un mio UserControl.

    Do per scontato che anche lo usercontrol deve avere un suo viewmodel. Se devo dalla windows contenitrice, interagire con le property dei controlli contenuti nello usercontrol, come faccio?

    grazie anticipate

    mercoledì 25 agosto 2010 10:18

Risposte

  • ciao,

    è un po' contorta la cosa, ma devi far puntare RelativeSource sulla window ed il path deve puntare al View Model contenuto nel DataContext. Anche io ho perso un po' di tempo cercando di imparare mvvm e questa era una delle prove che avevo fatto. Prova questo

    <local:UcTest x:Name="uc1" MyDp="{Binding Path=DataContext.Test, Mode=TwoWay, 
        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" >

    spero di esserti stato d'aiuto.

    Bye

    • Contrassegnato come risposta Luigi_M venerdì 27 agosto 2010 12:23
    giovedì 26 agosto 2010 14:58

Tutte le risposte

  • ll tuo usercontrol si deve comportare esattamente come tutti gli altri controlli di WPF e sopratutto dall'esterno non devi *mai* accedere a ciò che sta all'interno dello UserControl, semmai è lo usercontrol che esporrà tutte le proprietà necessarie al proprio funzionamento, possibilmente come Dependency Properties in modo che possano essere poi bindate al ViewModel associato alla finestra che lo contiene.
    Corrado Cavalli [Microsoft .NET MVP-MCP]
    UGIdotNET - http://www.ugidotnet.org
    Weblog: http://blogs.ugidotnet.org/corrado/
    Twitter: http://twitter.com/corcav
    mercoledì 25 agosto 2010 10:33
    Moderatore
  • le Dependency Properties che esporrò, presumo siano nel code behind dello user control.  Ho creato la seguente Dependency

    public static DependencyProperty MyDpProperty =
        DependencyProperty.Register("MyDp", typeof(string), typeof(UcTest),
        new UIPropertyMetadata("DEFAULT", UcTest.MyDpPropertyChanged, UcTest.Valore, false));

    public String MyDp
    {
        get
        {
            return (String)GetValue(MyDpProperty);
        }
        set
        {
            SetValue(MyDpProperty, value);
        }
    }

    private static void MyDpPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        UcTest inst = (UcTest)d;
        if ((string)e.NewValue == "")
        {
            //....Quà cosa va settato ???????
        }
    }

    private static object Valore(DependencyObject d, object value)
    {
        return value;
    }

     

    Questa Dependency Properties (che spero sia corretta.........scusami ma ho pochissima esperienza in WPF) l'ho messa in binding con la mia textbox contenuta nello user control <TextBox Text="{Binding MyDp}" ... Poi nella window contenitrice ho messo in binding la Dependency Properties, con una property Test dichiarata nel ViewModel del contenitore: MyDp="{Binding Test, Mode=TwoWay}"

    Ho però un errore nell'output di progetto: BindingExpression path error: 'MyDp' property not found on 'object' ''InitialPageViewModel'. Ma la Dependency Properties  MyDp è dichiarata nel code behind dello user control, come mai viene cercata nel viewmodel?

    Doov'è che sbaglio?

     

    Grazie per l'aiuto

    mercoledì 25 agosto 2010 13:37
  • Un passo avanti l'ho fatto:

    nella mia textbox contenuta nello user control ora il codice diventa:

    <TextBox Text="{Binding MyDp}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}, AncestorLevel=1}}"

    e ora il Binding "cerca" la property MyDp non nel viewmodel del contenitore ma in quello dello usercontrol.

    GOLD 

    giovedì 26 agosto 2010 13:18
  • Mi pare esattamente quello che deve fare, lo UC non deve dipendere dal viewmodel principale, devi solamente mettere la DP dello UserControl in binding con la proprietà del VM principale.
    Corrado Cavalli [Microsoft .NET MVP-MCP]
    UGIdotNET - http://www.ugidotnet.org
    Weblog: http://blogs.ugidotnet.org/corrado/
    Twitter: http://twitter.com/corcav
    giovedì 26 agosto 2010 13:42
    Moderatore
  • ok, ma adesso ho l'ultimo problema spero:

    ho aggiunto allo usercontrol un suo viewmodel e adesso, è la windows contenitrice a cercare la property Test nel viewmodel dello UC e non la trova perchè è dichiarata nel viewmodel del contenitore ovviamente.

     <local:UcTest x:Name="uc1" MyDp="{Binding Test, Mode=TwoWay}" >  --> BindingExpression path error: 'Test' property not found on 'object' ''UCViewModel'

    coma va dichiarato il binding in questo caso?

    giovedì 26 agosto 2010 14:21
  • ciao,

    è un po' contorta la cosa, ma devi far puntare RelativeSource sulla window ed il path deve puntare al View Model contenuto nel DataContext. Anche io ho perso un po' di tempo cercando di imparare mvvm e questa era una delle prove che avevo fatto. Prova questo

    <local:UcTest x:Name="uc1" MyDp="{Binding Path=DataContext.Test, Mode=TwoWay, 
        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" >

    spero di esserti stato d'aiuto.

    Bye

    • Contrassegnato come risposta Luigi_M venerdì 27 agosto 2010 12:23
    giovedì 26 agosto 2010 14:58