0

I'm new to WPF and the MVVM pattern so keep that in mind.

The project I'm tasked with working on has a view and a view model. The view also contains a user control that does NOT have a view model. There is data (custom object ... Order) being passed to the view model that I also need to share with the user control.

It looks like the UserControl does share data between the view model already via DependencyPropertys but this data is just text boxes on the user control that look to be bound back to propertys on the view model.

I need to share data that will NOT be represented by a control on the user control. Is there a good way to pass this data (complex Order object)? Maybe I do need some kind of hidden control on my user control to accomplish this but I'm just not that sure being new to this. Any advice would be appreciated.

Cole W
  • 15,123
  • 6
  • 51
  • 85
  • can you please give an example? "I need to share data that will NOT be represented by a control on the user control" frase in confusing... – Tigran Sep 01 '11 at 12:30
  • @Tigran I think he means things that won't be displayed, for example if you had a validation user control with a regex you wouldn't display the regex but you might be given it from a view model. Although I agree it's not entirely clear. – ForbesLindesay Sep 01 '11 at 12:36
  • @Tuskan360, Yes this is what I mean. I have an Order object in my view model that I will use to populate a Viewport3D object in my user control. My order object is just data being passed from my view model to my user control but is not directly being displayed in my user control. Most examples that I see of sharing data like this are text boxes or something similar. That's why I was saying that my data would not be represented by a control on the user control. – Cole W Sep 01 '11 at 13:06
  • @Cole that clarifies things a lot, do the answers below help or is something still not clear? – ForbesLindesay Sep 01 '11 at 13:13

2 Answers2

1

There is no need for hidden fields (or any such concept in WPF) as you can add any custom properties you want to a user control.

In the user control, create a new dependancy property like this but with MyUserControl set apropriately:

    public Order CurrentOrder
    {
        get { return (Order)GetValue(CurrentOrderProperty); }
        set { SetValue(CurrentOrderProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CurrentOrder.  This enables binding, etc.
    public static readonly DependencyProperty CurrentOrderProperty =
        DependencyProperty.Register("CurrentOrder", typeof(Order), typeof(MyUserControl), new PropertyMetadata(null, OnCurrentOrderPropertyChanged));

    public static void OnCurrentOrderPropertyChanged(DependencyObject Sender, DependencyPropertyChangedEventArgs e)
    {
        var sender = Sender as MyUserControl;
        var NewValue = e.NewValue as Order;
        var OldValue = e.OldValue as Order;
        if (OldValue != null && sender != null)
        {
            //Use old value as needed and use sender instead of this as method is static.
        }
        if (NewValue != null && sender != null)
        {
            //Use new value as needed and use sender instead of this as method is static.
        }
    }

In you're parent view where you use the usercontrol you then write something like:

<local:MyUserControl CurrentOrder="{Binding ViewModelOrder}" />

Where CurrentOrder is the dependancy property on the usercontrol and ViewModelOrder is the name of the property in the view model you would need to replace local:MyUserControl with your control name/namespace.

ForbesLindesay
  • 10,482
  • 3
  • 47
  • 74
  • +1 Very good clear explanation. Thanks for clearing this up for me. Makes perfect sense now. It works now! – Cole W Sep 01 '11 at 13:37
1

You can simply create a dependency property in the class of your UserControl and bind to it in the View that uses the control. There is no need to internally bind the dependency property to one of the controls in the UserControl.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443