[英]DataGrid CellStyle Setters with Freezable StaticRecource
I wanted to set the command of a button in a WPF datagrid with a setter. 我想使用设置器在WPF数据网格中设置按钮的命令。 But it seems that the DP property
CommandProperty
gets ovewritten with its default value null
after I returned a copy in CreateInstanceCore()
, so the original command gets lost. 但是,当我在
CreateInstanceCore()
返回副本后,似乎DP属性CommandProperty
的默认值null
被覆盖,因此原始命令丢失了。
If I bind the StaticResource
directly it works without problems. 如果我直接绑定
StaticResource
,它将正常工作。 Is there a way to stop that behavior or another solution? 有没有办法阻止这种行为或其他解决方案?
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: 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>
It works if you define your resource commands like this: 如果您这样定义资源命令,它将起作用:
<local:ResourceCommand x:Key="FirstCommand" Command="{Binding FirstCommand}" x:Shared="False"/>
Using this technique you can even throw not-implemented in CreateInstanceCore
and so you'll just be using Freezable
to enable data binding. 使用这种技术,您甚至可以在
CreateInstanceCore
不使用它,因此您将仅使用Freezable
启用数据绑定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.