DataGrid CellStyle Setters with Freezable StaticRecource

时间:2011-01-25 13:49:46

标签: c# wpf datagrid

我想使用setter在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 :(得分:0)

如果你定义这样的资源命令,它会起作用:

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

使用此技术,您甚至可以在CreateInstanceCore中执行未实现,因此您只需使用Freezable启用数据绑定。