Implementing a view-model-first approach inside a parent view/view model using MEFedMVVM - wpf

I am writing a WPF application using MEF and a third-party library called MEFedMVVM.
I am attempting to create a design whereby a parent view model has a collection of child view models, and I wish to use the view-model-first approach as this keeps the views outside of the view models thereby keeping the code more view model-centric and more unit testable.
I have read this discussion and this discussion regarding using DataTemplate for the view, and also Reed Copsy, Jr's suggestion here to use a generic view to view model mapping resource. But, I'm struggling to actually implement something that works.
My parent view is very simple:
<UserControl x:Class="MyParentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF"
meffed:ViewModelLocator.ViewModel="MyParentViewModel" />
The parent view model derives from a base type that implements IContextAware:
[ExportViewModel("MyParentViewModel")]
public class MyParentViewModel : ViewModelBase
{
[ImportingConstructor]
public MyParentViewModel()
{
var myChildVM = ServiceLocator.Current.GetInstance<MyChildViewModel>());
}
}
This is the child view model:
[Export(typeof(MyChildViewModel))]
[ExportViewModel("MyChildViewModel", true)]
public class MyChildViewModel : ViewModelBase
{
}
And this has a corresponding view:
<UserControl x:Class="MyChildView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF"
meffed:ViewModelLocator.ViewModel="MyChildViewModel" />
Initially, I thought that specifying the second Boolean parameter on ExportViewModel attribute for MyChildViewModel would make everything work using a view-model-first approach as my views and view models are MEFed together in the views' XAML code. However, turns out this is not the case, and what I actually get passed in to IContextAware.InjectContext() when I instantiate a MyChildViewModel object in the MyParentViewModel constructor is a MyParentView object. Not a MyChildView object as I was expecting and hoping. Clearly, I need to add something to wire them up together. Could anyone provide an example on how to do this?
Thanks!

When you really want to use view-model-first then you should do:
[ExportViewModel("MyParentViewModel")]
public class MyParentViewModel : ViewModelBase
{
// Create property for your child vm
public MyChildViewModel Child {get; private set}
// If you do MEF use constructor injection instead of servicelocator
[ImportingConstructor]
public MyParentViewModel(MyChildViewModel child)
{
this.Child = child;
}
}
then define a datatemplate for your childvm
<DataTemplate DataType="{x:Type local:MyChildViewModel}">
<view:MyChildViewUserControl />
</DataTemplate>
in your MainView you know where you want to show the child data, otherwise you wouldn't need the child property ;) so simply put a ContentControl where the Child data should go and bind to your property.
e.g.
<TabControl>
<TabItem Header="MyChildData">
<ContentControl Content="{Binding Child}" />
</TabItem>
</TabControl>
PS: Code is written without IDE, so errors possible :)

Related

How to show ContentControl in designer when using Calibrun.Micro viewModel-first approach?

I'm using Caliburn.Micro (CM) in a WPF application with ViewModel-first approach. I'm composing the main view with a command bar and an active item. Main viewModel sets the property for the command bar viewModel, and navigates to active item correctly.
Everything looks fine at runtime, the issue is only related to design-time: the main view shows empty in designer and I cannot find how to set it correctly. I managed to having this working in other scenarios, e.g. when setting the datacontext at design time for a whole Window or UserControl, i.e. when that's the root UI element in XAML. But now I'm not able to to this for child ContentPresenter UI elements within a Window.
This is an excerpt of the main view I'm composing:
<Window x:Class="...MainView" ...>
<DockPanel ...>
<!-- this one binds to a property of type CommandBarViewModel -->
<ContentControl x:Name="CommandBar" ... />
<ContentControl x:Name="ActiveItem" ... />
</DockPanel>
</Window>
I've checked a number of related reads, but none of them seems to fit/solve my issue. This question is basically the same as mine, but has no answers. That has a reference to this other question which it seems to me is going for a View-first approach, judging by the cal:View.Model bindings.
I tried adding a design-time context like the following (fake namespace not shown for brevity):
<ContentControl x:Name="CommandBar" ...
d:DataContext="{d:DesignInstance Type=fake:DesignTimeCommandBarViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True"/>
but then I incur in one of two cases:
if DesignTimeCommandBarViewModel inherits from the actual CommandBarViewModel, then I incur in somewhat the usual problem of design-time Vs dependency injection: the default constructor passes null for all injected dependencies, and base constructor or something else gives problem. I mean, it seems it would take some effort to find a workaround for this, and just for design-time support
if DesignTimeCommandBarViewModel does not inherit from the actual viewModel, then it seems that (correctly) the CommandBarView is not instantiated, as now there's no relationship anymore between the viewModel and that view.
Have you got any idea about this? Maybe this should be solved with a design-time version of the hosting MainViewModel?
Other references I checked: this answer, from Rob Eisenberg himself, this CM thread, this other SO
Edit
Following my last (auto-)hint, I'm trying also creating and instantiating a DesignTimeMainViewModel, not inheriting from MainViewModel, which exposes the same properties and sets a DesignTimeCommandBarViewModel in its default constructor. In this case, in place of the command bar the designer shows the classic CM complaint: cannot find view for the DesignTimeCommandBarViewModel.
What's next?
Well, here's the solution I found: I'd be glad to hear about better ways or other suggestions.
Host MainView XAML specifies a design-time data-context pointing to a design-time version of the Main view-model which, by the way, does not inherit from the runtime version MainViewModel. ContentControl items are left untouched.
<Window x:Class="...MainView" ...
d:DataContext="{d:DesignInstance Type=fake:DesignTimeMainPanelViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True">
<DockPanel ...>
<ContentControl x:Name="CommandBar" ... />
<ContentControl x:Name="ActiveItem" ... />
</DockPanel>
</Window>
DesignTimeMainPanelViewModel has the same public properties as MainPanelViewModel, has a default c'tor without dependencies and its c'tor sets the CommandBar property to a new instance of DesignTimeCommandBarViewModel:
public class DesignTimeMainPanelViewModel
{
public DesignTimeMainPanelViewModel()
{
CommandBar = new DesignTimeCommandBarViewModel();
ActiveItem = ...some instance here as well...;
}
public DesignTimeCommandBarViewModel CommandBar { get; private set; }
public IScreen ActiveItem { get; private set; }
}
DesignTimeCommandBarViewModel class is decorated with a custom Attribute having only one required parameter, the System.Type of the view associated with that view-model.
During bootstrap the code adds a new ViewLocator strategy to get the view Type from the view-model Type, by setting a new ViewLocator.LocateTypeForModelType.
The new locator function will try to find a view Type if the standard locator function cannot find one. Granted, it will look for the custom attribute on view-model Type, and if found that would be the returned view Type. Here's the gist of that:
Type viewType = _previousLocate(viewModelType, displayLocation, context);
if (viewType == null)
{
FakeViewAttribute fakeViewAttr = Attribute.GetCustomAttribute(viewModelType, typeof(FakeViewAttribute)) as FakeViewAttribute;
if (fakeViewAttr != null) viewType = fakeViewAttr.ViewType;
}
return viewType;

Removing UserControl code behind for use with MVVM

I am trying to create a user control using MVVM.
Basically I am trying to wrap a combobox that will pull data from a respository. This will allow me to use the same combobox in many different views in my application. There will be many of the wrapped comboboxes throughout the application.
I was easily able to create this control using a DependencyProperty and code-behind. I am now trying to convert this to MVVM and am having trouble figuring out how to get the value back to /from the ViewModel that in bound to the View where my combobox is located.
Any ideas or suggestions would be greatly appreciated at this point.
Thanks,
Eric
It is perfectly acceptable to use a UserControl that has code behind in it when using MVVM. If you really want to move the functionality out of the UserControl, then move it to whichever parent view models will require it. If you don't want to have the same code repeated in several places, you could encapsulate it in a class and add an instance of that class as a property to each of the relevant view models.
if you have a viewmodel that will pull data from a respository - you can use the same viewmodel in many different viewmodels in your application :)
and if you use a datatemplate your views know how to render this viewmodel
<DataTemplate DataType="{x:Type local:MyPullDataViewmodel}">
<view:MyCoolPullDataShowComboboxUserControl />
</DataTemplate>
It's pretty easy.
Let's say you have:
MyUserControlView.xaml
MYUserControlViewModel.cs
MyMainWindowView.xaml - For your MainWindow view (the one containing the UserControl)
MyMainWindowViewModel.cs - Your MainWindow ViewModel.
And you want to bind List<string> MyListToBind
And leave the code-behind completely empty.
MyUserControlViewModel.cs
public class MyUserControlViewModel
{
private List<string> _MyListToBind;
public List<string> MyListToBind { get; set;}
}
MyMainWindowViewModel.cs
public class MyUserControlViewModel
{
private MyUserControlViewModel _MyControlViewModel;
public MyUserControlViewModel MyControlViewModel { get; set;}
}
MyMainWindowView.xaml
<Window ...
xmlns:my="clr-namespace:NamespaceContainingYourUserControlView>
<my:MyUserControlView DataContext = "{Binding Path= MyControlViewModel}"/>
</Window>
MyUserControlView.xaml
<UserControl ...>
<DataGrid ItemsSource = "{Binding Path= MyListToBind}" .../>
...
</DataGrid>
</UserControl>
This doesn't support ViewModel updating View. To do that You have to use either DependencyProperties as you did instead of normal variables (as i did) or use INotifyPropertyChanged(google it, you'll get tons of examples) and OnPropertyChanged event.
You might read up on DataTemplates they are really useful in data binding.
You can find this usefeul:
http://www.youtube.com/watch?v=BClf7GZR0DQ
I sure as hell did !
Good luck.

How do you pass a ViewModel to the constructor of a UserControl that is shown in a ContentPresenter?

I have several UserControls that should display the same data. Each UserControl has a different layout of the data that is to be presented. The ContentPresenter can bind to any one of the UserControls by using a DataTemplate in my Resources and by binding the Content to a StyleViewModel. Each UserControl is associated with a ViewModel as defined in the DataType of the DataTemplate. The ViewModels associated with any given UserControl all inherit from the StyleViewModel. The UserControls should get their data from a SettingsViewModel. The UserControls appear in the main Window.
The problem is that I can't figure out how to make the data from the SettingsViewModel accessible to the UserControls.
Is it possible to pass a reference to a SettingsViewModel to the constructor of one of these UserControls that are displayed using a ContentPresenter?
Is there another way to easily switch between different views of the data (i.e. my UserControls) without using a ContentPresenter? If so, how would I make the data accessible to the UserControls?
The following is code from my SingleLineViewModel.cs:
public class SingleLineViewModel : StyleViewModel
{
public SingleLineViewModel() { }
}
The other ViewModels are similar. They are essentially empty classes that inherit from StyleViewModel, so that I can bind to a Style property which is of type StyleViewModel in my SettingsViewModel. The StyleViewModel is also an essentially empty class that inherits from ViewModelBase.
The following is code from my Resources.xaml:
<ResourceDictionary <!--other code here-->
xmlns:vm="clr-namespace:MyProject.ViewModel"
<!--other code here-->
<DataTemplate DataType="{x:Type vm:SingleLineViewModel}">
<vw:ucSingleLine/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SeparateLinesViewModel}">
<vw:ucSeparateLines/>
</DataTemplate>
<!--other code here-->
</ResourceDictionary>
The following is code from SettingsViewModel.cs:
public class SettingsViewModel : ViewModelBase
{
// other code here
private StyleViewModel _style;
public StyleViewModel Style
{
get { return _style; }
set
{
if (value != _style && value != null)
{
_style = value;
OnPropertyChanged("Style");
}
}
}
// other code here
public SettingsViewModel()
{
_style = new SingleLineViewModel();
}
// other code here
}
The following is code from my MainView.xaml:
<ContentPresenter Name="MainContent" Content="{Binding SettingsVM.Style}"/>
You might find that you are trying to do much at once. Consider how you might test this scenario? Or how would you walk the data in a Debugger to check its state? Good practice recommends that your data is separate from your UI elements. An MVVM pattern such as you are trying to use normally provides the view models to help transition the data from it's simple data into forms that the UI can use.
With that in mind, I would recommend that you try do develop a ViewModel tier that presents all the data without the UI holding it together, i.e. instead of trying to inject the additional SettingsViewModel into your controls you should make your viewmodels hold everything they need.
It looks like you are off to a good start, your SettingsViewModel lets you get hold of a Style, but your style doesn't seem to have any data. So why not pass it in the constructor.
public SettingsViewModel()
{
_style = new SingleLineViewModel(WhatINeedForStyle);
}

Nested Data Context with Unity

I took a course on VB.Net + WPF at university last year. For the final project, I decided to give MVVM a go (we hadn't discussed it at all in the course, I had just researched it and thought it would be a useful exercise). It was a good experience however I'm rather sure I might have made some poor choices when it came to design.
I've since graduated and my job has nothing to do with WPF or Windows development however I'm developing a small application in my own time and thought it would be fun to use C# and WPF (C# is a language I very much like to work with and I enjoyed working with WPF so it's a pretty logical choice).
Anyway, I'm using this as an opportunity to learn more about MVVM and try and implement it in a better way than I did previously. I've done a bit more reading and am finding it a lot easier to graph than I had when trying to implement it alongside learning WPF.
I've used In The Box MVVM Training as a guide and will be using Unity for dependency injection at this.
Now, in the sample app developed in the guide, there is a single view model (MainWindowViewModel). The MainWindow is pretty much a container with 3 or 4 UserControls which all share the DataContext of the MainWindow.
In my app, I'd like to have a tab-based interface. As such, the MainWindow will be primary concerned with displaying a list of buttons to switch the current view (i.e. move from the 'add' view to the 'list view'). Each view will be a self-contained UserControl which will implement it's own DataContext.
The same code in the app is as follows:
MainWindow window = container.Resolve<MainWindow>();
window.DataContext = container.Resolve<MainWindowViewModel>();
window.Show();
That's fine for setting data context of the MainWindow, however how will I handle assigning each user context it's own ViewModel as a DataContext?
EDIT: To be more specific, when I say tab-based interface, I don't mean it in the sense of tabs in a text editor or web browser. Rather, each 'tab' is a different screen of the application - there is only a single active screen at a time.
Also, while Slauma's post was somewhat helpful, it didn't really explain how I'd go about injecting dependencies to those tabs. If the NewStatementView, for example, was required to output it's data, how would I inject an instance of a class that implements the 'IStatementWriter' interface?
EDIT: To simplify my question, I'm basically trying to figure out how to inject a dependency to a class without passing every dependency through the constructor. As a contrived example:
Class A has Class B.
Class B takes as a constructor paramater needs an implementation of Interface I1.
Class B uses Class C.
Class C takes as a constructor paramater needs an implementation of Interface I2.
How would I handle this scenario using DI (and Unity)? What I don't want to do is:
public class A(I1 i1, I2 i2) { .... }
I could register everything using Unity (i.e. create I2, then C, then I1 and B, and then finally insert these into A) but then I would have to instantiate everything when I want to use A even if I might not even need an instance of B (and what if I had a whole bunch of other classes in the same situation as B?).
MVVM has lots of benefits, but in my experience wiring up the view models and the views is one of the biggest complexities.
There are two main ways to do this:
1:
Wire the view models to the views.
In this scenario, the XAML for the MainWindow contains the child controls. In your case, some of these views would probably be hidden (because you are only showing one screen at a time).
The view models get wired to the views, usually in one of two ways:
In the code behind, after the InitializeComponents() call or in a this.Loaded event handler, let this.DataContext = container.Resolve<MyViewModelType>();
Note that in this case the container needs to be globally available. This is typical in applications that use Unity. You asked how children would resolve interfaces like IStatementWriter. If the container is global, the child view models could simply call container.Resolve<IStatementWriter>();
Another way to wire the view models into the views is to create an instance of the view model in XAML like this:
<UserControl ...>
<UserControl.DataContext>
<local:MyViewModelType/>
</UserControl.DataContext>
...
</UserControl>
This method is not compatible with Unity. There are a few MVVM frameworks that allow you to resolve types in XAML (I believe Caliburn does). These frameworks accomplish this through markup extensions.
2:
Wire the view up to the view model.
This is usually my preferred method, although it makes the XAML tree more complicated. This method works very well when you need to perform navigation in the main view model.
Create the child view model objects in the main view model.
public class MainViewModel
{
public MyViewModelType Model1 { get; private set; }
public ViewModelType2 Model2 { get; private set; }
public ViewModelType3 Model3 { get; private set; }
public MainViewModel()
{
// This allows us to use Unity to resolve the view models!
// We can use a global container or pass it into the constructor of the main view model
// The dependencies for the child view models could then be resolved in their
// constructors if you don't want to make the container global.
Model1 = container.Resolve<MyViewModelType>();
Model2 = container.Resolve<ViewModelType2>();
Model3 = container.Resolve<ViewModelType3>();
CurrentViewModel = Model1;
}
// You will need to fire property changed notifications here!
public object CurrentViewModel { get; set; }
}
In the main view, create one or more content controls and set the content(s) to the view models that you want to display.
<Window ...>
...
<ContentControl Content="{Binding CurrentViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type local:MyViewModelType}">
<local:MyViewType/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelType2}">
<local:ViewType2/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelType3}">
<local:ViewType3/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
...
</Window>
Notice that we tie the child views to the view models through data templates on the ContentControl. These data templates could have been defined at the Window level or even the Application level, but I like to put them in context so that it's easier to see how the views are getting tied to the view models. If we only had one type of view model for each ContentControl, we could have used the ContentTemplate property instead of using resources.
EDIT: In this method, the view models can be resolved using dependency injection, but the views are resolved through WPF's resource resolution mechanism. This is how it works:
When the content for a ContentPresenter (an underlying component in the ContentControl) is set to an object that is NOT a visual (not derived from the Visual class), WPF looks for a data template to display the object. First it uses any explicit data templates set on the host control (like the ContentTemplate property on the ContentControl). Next it searches up the logical tree, examining the resources of each item in the tree for a DataTemplate with the resource key {x:Type local:OBJECT_TYPE}, where OBJECT_TYPE is the data type of the content. Note that in this case, it finds the data templates that we defined locally. When a style, control template, or data template is defined with a target type but not a named key, the type becomes the key. The Window and Application are in the logical tree, so resources/templates defined here would also be found and resolved if they were not located in the resources of the host control.
One final comment. If a data template is not found, WPF calls ToString() on the content object and uses the result as the visual content. If ToString() is not overridden in some meaningful way, the result is a TextBlock containing the content type.
<--
When you update the CurrentViewModel property on the MainViewModel, the content and view in the main view will change automatically as long as you fire the property changed notification on the main view model.
Let me know if I missed something or you need more info.
For a Tab-based interface this classical article about MVVM pattern in WPF might be very useful. (It also offers a downloadable sample application.)
The basic idea to connect each tab with a UserControl is as follows (only a rough sketch, details are in the article):
The MainWindow View has a ContentControl ...
<ContentControl Content="{Binding Path=Workspaces}"
ContentTemplate="{StaticResource WorkspacesTemplate}" />
... which binds to a collection of "Workspaces" in the MainWindowViewModel:
public ObservableCollection<WorkspaceViewModel> Workspaces { get; private set; }
This WorkspaceViewModel serves as a base class for all ViewModels you want to display as a tab.
The WorkspacesTemplate is a DataTemplate which binds a TabControl to the collection of WorkspaceViewModels:
<DataTemplate x:Key="WorkspacesTemplate">
<TabControl IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}" />
</TabControl>
</DataTemplate>
And for every specific Tab you have a UserControl with a ViewModel which derives from WorkspaceViewModel ...
public class MySpecialViewModel : WorkspaceViewModel
... and which is related to the UserControl by a DataTemplate:
<DataTemplate DataType="{x:Type vm:MySpecialViewModel}" >
<v:MySpecialUserControl />
</DataTemplate>
Now, if you want to open a tab you would have a Command in the MainWindowViewModel which creates the ViewModel belonging to that tab and add it to the Workspaces collection of the MainWindowViewModel:
void CreateMySpecialViewModel()
{
MySpecialViewModel workspace = new MySpecialViewModel();
Workspaces.Add(workspace);
}
The rest is done by the WPF binding engine. The TabControl recognizes automatically that this special workspace item in the collection is of type MySpecialViewModel and selects the right View/UserControl through the DataTemplate we have defined to connect ViewModel and View and displays it in a new Tab.
At the point where you resolve your Views deriving from UserControl, use property injection to resolve a new ViewModel for each one and set the DataContext property of the view to it.

WPF + MVVM - How to bind a property to the parent view's data context

Working with the MVVM pattern, I have a pair of view model classes that represent a two-tier data hierarchy, each with a corresponding UserControl that represents its view. Both view model classes implement INotifyPropertyChanged and the root level view model exposes a property that is relevant to both its own view and the child view.
The root level view acquires the root level view model as its data context and explicitly assigns a data context to its contained view. However, it also needs to bind one of the properties of the child view to the above-mentioned shared property. Here is how I have attempted to achieve this, but it's not working:
<UserControl x:Name="rootView">
<StackPanel>
<!-- other controls here -->
<my:ChildView
DataContext="{Binding Path=SelectedChild}"
EditingMode="{Binding ElementName=rootView, Path=DataContext.EditingMode />
</StackPanel>
</UserControl>
Although there are no runtime binding errors and the child view correctly binds to the appropriate child view model instance, its EditingMode property is never set. I have run tests to verify that the corresponding view model property is being modified and that it is notifying this change via INotifyPropertyChanged, but the binding fails to detect it.
Is there a better way to declare this binding or have I made a more basic architectural error?
Many thanks for your advice,
Tim
Update: As requested, I am posting some code to show a very simplified version of my views and view models, together with the results of an experiment that I have conducted that may provide some additional clues.
// The relevant parts of the ParentViewModel class
public class ParentViewModel : INotifyPropertyChanged
{
// Although not shown, the following properties
// correctly participate in INotifyPropertyChanged
public ChildViewModel SelectedChild { get; private set; }
public ContentEditingMode EditingMode { get; private set; }
}
// The relevant parts of the ChildViewModel class
public class ChildViewModel : INotifyPropertyChanged
{
// No properties of ChildViewModel affect this issue.
}
// The relevant parts of the ParentView class
public partial class ParentView : UserControl
{
// No properties of ParentView affect this issue.
}
// The relevant members of the ChildView class
public partial class ChildView : UserControl
{
public static readonly DependencyProperty EditingModeProperty =
DependencyProperty.Register(
"EditingMode",
typeof(ContentEditingMode),
typeof(PostView)
);
public ContentEditingMode EditingMode
{
get { return (ContentEditingMode)GetValue(EditingModeProperty); }
set { SetValue(EditingModeProperty, value); }
}
}
// The enumeration used for the EditingMode property
public enum ContentEditingMode
{
Html,
WYSYWIG
}
My intention is that the DataContext of the parent view instance will be assigned an instance of ParentViewModel and it will, in turn, assign the value of its SelectedChild property to the DataContext of the nested ChildView. All of this seems to work correctly, but the problem arises because the binding between ParentViewModel.EditingMode and ChildView.EditingMode does not work.
In an attempt to test whether there is a problem with my binding expression, I introduced a TextBlock adjacent to the ChildView and bound it similarly to the ParentViewModel.EditingMode property:
<UserControl x:Name="rootView">
<StackPanel>
<!-- other controls here -->
<TextBlock Text="{Binding ElementName=rootView, Path=DataContext.EditingMode}" />
<my:ChildView
DataContext="{Binding Path=SelectedChild}"
EditingMode="{Binding ElementName=rootView, Path=DataContext.EditingMode />
</StackPanel>
</UserControl>
In this test, the TextBlock is correctly updated every time the source property changes. However, if I set a breakpoint on the setter of ChildView.EditingMode, it never gets hit.
I'm baffled !
The simplest way to fix this is in your view model. Implement an EditingMode property in the child view model and bind to it. That way, you don't have to make any kind of guesses about what the right way to establish the binding might be; also, it's something that you can test outside of the UI.
Edit
Actually the right solution is not quite as simple, but it's worth knowing how to do.
What you want is for EditingMode in the child control to efficiently inherit its value from the parent control. Does that sound like something that anything else in WPF does? Like just about every framework element that implements dependency properties?
Implement EditingMode as a dependency property in both the parent and child UserControls and use property value inheritance, as described here. That takes the inheritance behavior out of the view model entirely and puts it where it belongs.
See if you can just use a full path to get the editing mode of the selected child:
<my:childView
DataContext="{Binding SelectedChild}"
EditingMode="{Binding SelectedChild.EditingMode />

Resources