wpffloatingavalondockcommandbindingcanexecute

Command Binding issues in AvalonDock


I have created an application where there's a series of command bindings attached to the MainWindow of my application:

(Code simplified for brevity)

<Window x:Class="DBBrowser.Design.Project.ProjectView" 
...>

    <Window.CommandBindings>
    <Commands:DataContextCommandBinding Command="ProjectCommands:ProjectRoutedCommands.OpenReferenceList" Executed="OpenReferenceList" CanExecute="CanOpenReferenceList"/>
...
</Window.CommandBindings>
</Window>

Within the project's ViewModel are two functions:

public bool CanOpenReferenceList(object parameter)
{
    return true;
}

public void OpenReferenceList(object parameter)
{
    var dockedReferenceList = new DockableUniversalListView()       
    {
        Name = "referenceList",
        Title = "Reference List"
    };
    referenceData = dockedReferenceList.DataContext as ReferenceListViewModel;
    if (referenceData != null) referenceData.EvListSelected += WoWObjectListRecieved;

    DockedWindows.Add(dockedReferenceList);
}

Skipping over a bunch of details, there are 3 scenarios where this Command can be called:

  1. As a DockableContent within the application's main window
  2. As a new Window control, containing the DockableContent
  3. As a FloatingWindow, created by "tearing off" the window via AvalonDock

Scenario #1 and #2 work perfectly using the following command binding:

<Button Margin="2" Content="Validate" Height="23" Name="Validate" Width="75" 
        Command="ProjectCommands:ProjectRoutedCommands.OpenReferenceList" 
        CommandTarget="{Binding Path=MainWindow.DataContext,Source={x:Static Application.Current}}" 
        DockPanel.Dock="Left"
        CommandParameter="{Binding Path=SelectedWoWObjectList}"
        TabIndex="20" HorizontalAlignment="Right"/>

However, when I "Tear off" the AvalonDock window, the button greys out. However, a stack trace showed that CanExecute() was being called AND returning true for that button... but the Button remained disabled.


Solution

  • The solution was that the CommandTarget binding was null - Application.Current.MainWindow is not set when the Constructor for the MainWindow is still being called.