views:

54

answers:

1

First of all sorry for my "pidgin" english, :(

Application was built on MVVM pattern. ViewModel exposes its functionality via commands & has special command - DispatchCommand which receives (in CommandParameter) pair of other Command/Parameter & executes received Command with received Parameter. The feature (rather unimportant for topic purposes) is that the DispatcherCommand is executing in primary application thread, other ViewModel commands (invoked by DispatcherCommand) is asynchronous, and each of them executes its Execute() delegate in separate thread. Such approach (indirect execution of async ViewModel commands via DispatchCommand) used in order to manage inner ViewModel state (for example, DispatchCommands refuses invocation of particular async command while other async command executes & so on).

In code it looks like:

// Dispatcher command
public class DispatcherCommand : ICommand { }

// async command
public interface IAsyncCommand : ICommand { }
public class AsyncCommand : IAsyncCommand { }

// view model
public class AsyncModel
{
    public DispatcherCommand Dispatcher { get {...} }

    // async commands - current model capabilities
    public AsyncCommand FirstCapability { get {...} }
    public AsyncCommand SecondCapability { get {...} }
    ...
}

// using example
AsyncModel model = new AsyncModel();
model.Dispatcher.Execute( 
   new { Command = model.FirstCapability, Parameter = "string param" });

I want provide access to async commands in the XAML in the same way:

<Button Command="{Binding Path=DispatcherCommand}">
    <Button.CommandParameter>
        <local:CurrentCommandParameters Command="{Binding Path=FirstCapability}"
                                        Parameter="string param"/>
    </Button.CommandParameter>Use first capability</Button>

where

    // DispatcherCommand parameter class
public class DispatcherCommandParameters : DependencyObject
{
    // target async command
    public IAsyncCommand Command
    {
        set { SetValue(CommandProperty, value); }
        get { return (IAsyncCommand)GetValue(CommandProperty); }
    }

    // its parameter
    public object Parameter
    {
        set { SetValue(ParameterProperty, value); }
        get { return GetValue(ParameterProperty); }
    }

    public static readonly DependencyProperty CommandProperty;
    public static readonly DependencyProperty ParameterProperty;

    static CurrentCommandParameters()
    {
        CommandProperty = DependencyProperty.Register("Command",
            typeof(IAsyncCommand),
            typeof(CurrentCommandParameters),
            new PropertyMetadata());

        ParameterProperty = DependencyProperty.Register("Parameter",
            typeof(object),
            typeof(CurrentCommandParameters),
            new PropertyMetadata());
    }
}

but it's not working. DispatcherCommand.Execute(object parameter) receives an instance of DispatcherCommandParameters class, but its Command property is null.

What can be done in this situation?


In window constructor the same binding, as failed in xaml, created successfully:

<Button Name="StupidButton" Command="{Binding Path=DispatcherCommand}">

...

public MainWindow()
{
    InitializeComponent();

    // set up data context
    AsyncModel model = new AsyncModel();
    this.DataContext = model;

    // set up binding
    DispatcherCommandParameters dcp = new DispatcherCommandParameters();
    dcp.Parameter = "string parameter value set in code";
    Binding myBinding = new Binding("FirstCapability");
    myBinding.Source = model;
    BindingExpressionBase be = BindingOperations.SetBinding(dcp, 
        DispatcherCommandParameters.CommandProperty, myBinding);
    StupidButton.CommandParameter = dcp;            

    // now when "StupidButton" is pressed, 
    // DispatcherCommand.Execute(object parameter)
    // receives correct reference to AsyncModel.FirstCapability command in 
    // ((DispatcherCommandParameters)parameter).Command property
}
A: 

If "Command" is null in your DispatcherCommandParameters, it is most likely just a binding issue, are there any warnings in your output window in visual studio?

JoshVarga
Unfortunately, there are no warnings in output window.
JSP