4

There are lots of questions like this one, but still can't get what I really want, and all of them have something that differs of mine and that is: I have a UserControl:

  • Built separately in a class library project called UCProject;
  • The project UCProject has a View for the control, and its ViewModel;
  • The UserControl binds some of its own controls and UIElements properties in the View to properties declared in the ViewModel in, of course, the UCProject;
  • How can I show or expose or make the ViewModel Properties accessible to the page or the window of the project (that may be called for instance GlobalProject) that may host this UserControl;

I'am building this UserControl, I want to build events, properties to it ... and I want it to be used by others as a given assembly to them, so its code is not accessible, they only can consume it, I want to respect the MVVM pattern, and I don't have a clear idea how to realize that, should I write this properties and events in the CodeBehind of the UserControl View or should I put them in the ViewModel, and in that case how can I access them from outside, just like we daily use third-party controls

AymenDaoudi
  • 7,811
  • 9
  • 52
  • 84

3 Answers3

4

If i assume it right, you want to expose properties of child UserControl's ViewModel to containing parent root element which might be window or other UserControl.

There are two approaches to it:

First, DataContext DP is inheritable i.e. child controls inherit it from parent control unless set it explicitly to some other value. So, what you can do is have common ViewModel and set it as DataContext on parent UserControl and both have access to its properties.


Second, in case you want separate ViewModels for parent and child UserControls. You can always access properties of child's ViewModel via DataContext. Let me explain with an example:

<UserControl x:Name="ParentUserControl">
   <StackPanel>
      <local:ChildUserControl x:Name="Child"/>
      <TextBlock Text="{Binding DataContext.PropertyName, ElementName=Child}"/>
   </StackPanel>
</UserControl>

where PropertyName is property in ViewModel of ChildUserControl.

Here as you can see TextBlock which lies in ParentUserControl is binding to property in ViewModel of child UserControl.

Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • I edited my question to be more clear now : For the 1st approach: I can't have the same ViewModel for both, the UserControl is in a separate project and it will be compiled and given as an assembly (library) so developers can consume it. For The 2nd approach: it's a nice solution, but generally when we consume UserControls built by others we don't have to use DataContext to access their properties we just do userControl.Property , hence I would do in XAML : does that mean something must be written in CodeBehind ?? – AymenDaoudi Dec 28 '13 at 09:32
  • No as long as Child UserControl exposes that property that will work as well. Nothing required in code behind. – Rohit Vats Dec 28 '13 at 09:45
  • How would I expose it to the exterior while it's declared in the ViewModel, I mean so I can access it like this UserControlInstance.Propertie1 = Value , just like we do daily with any third-party Control – AymenDaoudi Dec 28 '13 at 09:50
  • You are confusing things here. `UserControlInstance.Propertie1 = Value` means Propertie1 is a property of control itself and not of its ViewModel. However, if you want to access property in ViewModel, you need to get DataContext like i mentioned in answer. – Rohit Vats Dec 28 '13 at 09:57
  • Yes that s exactly what I'm talking about , I'm talking about properties of the UserControls its self, I said that I want to build the UserControl using MVVM, so I want to implement them in the ViewModel, is it wrong to do so ? – AymenDaoudi Dec 28 '13 at 10:01
  • No nothing wrong in it. If it's only UserControl properties you interested in from outside, then this piece of code is completely fine - ``. – Rohit Vats Dec 28 '13 at 10:18
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44050/discussion-between-aymendaoudi-and-rohit-vats) – AymenDaoudi Dec 28 '13 at 10:20
  • 1
    Are you still looking for the answer to your question? I thought your problem was solved. – Rohit Vats Dec 28 '13 at 19:27
  • Ok great. I was wondering since you didn't accepted an answer. – Rohit Vats Dec 29 '13 at 07:15
0

You haven't specifically declared which parts of these projects you have control over so I'll assume you can changed all of them. Basically you need to use dependency properties in the User Control. First you bind the view to the ViewModel, when you add the User Control to the view it will effectively inherit the DataContext and you can bind the dependency properties you've created to the various parts of the ViewModel. In the User Control itself you bind the various FrameworkElements to the dependency properties in the User Control, not to the ViewModel itself.

Make sense?

Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • 1
    I have Control over the global object the UserControl project is developed and given in an assembly to be consumed by developers just as we consume third-party controls, the consumer developer can't access the code of the UserControl, how can I expose the Properties I build for this UserControl in the ViewModel, or am I obliged to write them in code behind – AymenDaoudi Dec 28 '13 at 09:35
0

I had to implement those Properties in the CodeBehind using DependencyProperties that's the best way to do it

AymenDaoudi
  • 7,811
  • 9
  • 52
  • 84