Search code examples
wpfcommandtoolbarmaster-detail

Master/Detail Toolbar Command binding


I have following App with a toolbar, Masters list and detail view:

Overview

The detail is "injected" via ContentControl. The detail contains a UserControl, which contains a ScrollViewer and so on. At some point there is a "ZoomPanControl" (not mine) which provides a command "FitView".

I want to execute the command "FitView" from my toolbar for the currently active detail view.

My toolbar button looks like this:

<fluent:Button x:Name="FitButton" Command="{Binding ?WhatGoesHere?}" Header="Fit View"/>

I can not figure out how to bind the command property of the toolbar button to the currently active ZoomPanControl. I don't even "see" this control when doing the command binding.

Any hint how this problem is generally solved is highly appreciated.


Solution

  • Here's how I solved the problem. Luckily I have access to the source code of the ZoomPanControl.

    First I have implemented a DependencyProperty in the ZoomPanControl for the "FitView" command like this:

    public static readonly DependencyProperty FitCommandDepPropProperty =   DependencyProperty.Register(
            "FitCommandDepProp", typeof (ICommand), typeof (ZoomAndPanControl),   new PropertyMetadata(default(ICommand)));
    
        public ICommand FitCommandDepProp
        {
            get { return (ICommand) GetValue(FitCommandDepPropProperty); }
            set { SetValue(FitCommandDepPropProperty, value); }
        }
    

    In the "OnApplyTemplate()" method of the control I set the dependency property:

    FitCommandDepProp = FitCommand;
    

    In the detail-View of my application I bind the command-dependency-property to my ViewModel like this:

    <zoomAndPan:ZoomAndPanControl x:Name="zoomAndPanControl" 
                                          FitCommandDepProp="{Binding FitCommand, Mode=OneWayToSource}"
    

    The important part is Mode=OneWayToSource. This "forwards" the command from the ZoomPanControl to my detail-viewmodel.

    Detail-viewmodel has property of ICommand to bind to. From this point on I have the command in my viewmodel logic. I have implemented a mechanism to pass the FitCommand to the viewmodel which is bound to the toolbar. You can use a event or whatever you prefer to pass the command around.

    The viewmodel of the toolbar has again a ICommand property for the FitCommand.

    public ICommand FitCommand
        {
            get { return _fitCommand; }
            set
            {
                if (Equals(value, _fitCommand)) return;
                _fitCommand = value;
                NotifyOfPropertyChange(() => FitCommand);
            }
        }
    

    In the toolbar-view I bind simply to this property:

    <fluent:Button x:Name="FitButton" Command="{Binding FitCommand}" Header="Fit View"/>
    

    After that, the view commands are available for each detail-view separately.

    But I have no idea how to solve this without access to the source code of the ZoomPanControl.