Использование пользовательского класса в XAML, чтобы его свойства служили местом назначения привязки - PullRequest
0 голосов
/ 31 августа 2010

Прежде всего извините за мой "пиджин" английский,: (

Приложение было построено по шаблону MVVM. ViewModel предоставляет свои функциональные возможности с помощью команд и имеет специальную команду - DispatchCommand, которая получает (в CommandParameter) пару других команд / параметров и выполняет полученную команду с полученным параметром. Функция (довольно неважная для тематических целей) состоит в том, что DispatcherCommand выполняется в основном потоке приложения, другие команды ViewModel (вызываемые DispatcherCommand) являются асинхронными, и каждая из них выполняет свой делегат Execute () в отдельном потоке. Такой подход (косвенное выполнение асинхронных команд ViewModel через DispatchCommand), используемый для управления внутренним состоянием ViewModel (например, DispatchCommands отказывается от вызова конкретной асинхронной команды, в то время как другая асинхронная команда выполняет и т. Д.).

В коде это выглядит так:

// 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" });

Я хочу предоставить доступ к асинхронным командам в XAML таким же образом:

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

, где

    // 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());
    }
}

но это не работает. DispatcherCommand.Execute (параметр объекта) получает экземпляр класса DispatcherCommandParameters, но его свойство Command имеет значение null.

Что можно сделать в этой ситуации?


В конструкторе окна успешно создана та же привязка, что и в xaml: Ошибка:

<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
}

1 Ответ

0 голосов
/ 31 августа 2010

Если в вашем DispatcherCommandParameters значение «Command» равно нулю, это, скорее всего, просто проблема привязки, есть ли какие-либо предупреждения в окне вывода в Visual Studio?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...