Сеттеры CellStyle DataGrid со статическим ресурсом Freezable - PullRequest
1 голос
/ 25 января 2011

Я хотел установить команду кнопки в сетке данных WPF с помощью установщика. Но похоже, что свойство DP CommandProperty переписывается со значением по умолчанию null после того, как я вернул копию в CreateInstanceCore(), поэтому оригинальная команда теряется.

Если я связываю StaticResource напрямую, он работает без проблем. Есть ли способ остановить это поведение или другое решение?

public class ResourceCommand : Freezable, ICommand {

    public ICommand Command {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(ResourceCommand), new UIPropertyMetadata(null, CommandPropertyChangedCallback));


    static void CommandPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        ResourceCommand resourceCommand = (ResourceCommand)d;
        int h = resourceCommand.GetHashCode();
        if (e.OldValue != null)
            ((ICommand)e.OldValue).CanExecuteChanged -= resourceCommand.OnCanExecuteChanged;
        if (e.NewValue != null)
            ((ICommand)e.NewValue).CanExecuteChanged += resourceCommand.OnCanExecuteChanged;
    }

    #region ICommand Member

    public bool CanExecute(object parameter) {
        if (Command == null)
            return false;
        return Command.CanExecute(parameter);
    }

    public event EventHandler CanExecuteChanged;

    void OnCanExecuteChanged(object sender, EventArgs e) {
        if (CanExecuteChanged != null)
            CanExecuteChanged(sender, e);
    }

    public void Execute(object parameter) {
        Command.Execute(parameter);
    }

    #endregion

    protected override Freezable CreateInstanceCore() {
        ResourceCommand ResourceCommand = new ResourceCommand();
        ResourceCommand.Command = Command;
        return ResourceCommand;
    }
}

XAML:

<Window.Resources>
    <local:ResourceCommand x:Key="FirstCommand"  Command="{Binding FirstCommand}" />
    <local:ResourceCommand x:Key="SecondCommand"  Command="{Binding SecondCommand}" />
</Window.Resources>
<Grid>
    <DataGrid ItemsSource="{Binding Collection}">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Click me">
                            <Button.Style>
                                <Style TargetType="Button">
                                    <Setter Property="Command" Value="{StaticResource FirstCommand}" />
                                </Style>
                            </Button.Style></Button>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

1 Ответ

0 голосов
/ 27 января 2011

Это работает, если вы определяете свои команды ресурсов следующим образом:

<local:ResourceCommand x:Key="FirstCommand" Command="{Binding FirstCommand}" x:Shared="False"/>

Используя эту технику, вы можете даже выбросить не реализованные в CreateInstanceCore, поэтому вы просто будете использовать Freezable для включенияпривязка данных.

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