I have a WPF app with interchangeable views. A view inherits from my ViewBase class:
public class ViewBase : ContentControl, IView
{
public ViewBase()
{
ToolbarGroups = new ObservableCollection<ToolbarGroup>();
}
public ObservableCollection<ToolbarGroup> ToolbarGroups
{
get { return (ObservableCollection<ToolbarGroup>)GetValue(ToolbarGroupProperty); }
private set { SetValue(ToolbarGroupProperty, value); }
}
public static readonly DependencyProperty ToolbarGroupProperty =
DependencyProperty.Register("ToolbarGroup", typeof(ObservableCollection<ToolbarGroup>), typeof(ViewBase));
}
I am binding the ToolbarGroups property to an ItemsControl in my window. It works great.
A ToolBarGroup inherits from HeaderedContentControl, and I wire them up inside a view like this:
<base:ViewBase x:Class="TestApp.Orders.OrderDetailsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:base="clr-namespace:TestApp"
xmlns:local="clr-namespace:TestApp.Orders"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="root">
<base:ViewBase.ToolbarGroups>
<base:ToolbarGroup Header="Group1">
<!-- Buttons and other controls go here -->
</base:ToolbarGroup>
<!-- Binding to MyProp is the problem -->
<local:PremadeToolbarGroup MyProp="{Binding}" />
<!-- This also doesn't work -->
<local:PremadeToolbarGroup MyProp="{Binding ElementName=root,Path=DataContext}" />
</base:ViewBase.ToolbarGroups>
<Grid>
<!-- this binding works -->
<TextBox Text="{Binding Path=Model.FullName}" />
</Grid>
</base:ViewBase>
The PremadeToolbarGroup is a XAML file that inherits from ToolbarGroup and adds some buttons. The PremadeToolbarGroup contains a dependency property called MyProp which I want to bind to the DataContext of the view its used on.
My DataContext is set to an object of type ViewModelBase, which is also the type for the MyProp dependency property.
The PremadeToolbarGroup shows up as expected, but the binding never works (MyProp is always null). Any thoughts?
I found a solution:
On my window, the view is shown in a ContentPresenter:
The content property is set to the View via the code-behind.
As I said in my question, “I am binding the ToolbarGroups property to an ItemsControl in my window.”
So I display the ToolbarGroups elsewhere in the window with this:
The ToolbarGroup objects couldn’t bind to the DataContext of the View because they were added to the visual tree outside the view.
I was able to fix it by binding the DataContext of each item in the ItemsControl to the DataContext of the ViewPresetner content. It looks like this:
It’s a bit messy but it works. I’m certainly open to a more elegant solution if anyone has one.