依赖项属性继承
我需要控制从类型网格的祖先继承UIElement.IsEnabledProperty(可选窗口或任何其他元素i可以包装我的网格)依赖项属性继承
CS:下面我重写UIElement的元数据.IsEnabledProperty并使用Change和Coerce代表进行设置。
static PipeControl()
{
PipeControl.IsEnabledProperty.OverrideMetadata(typeof(PipeControl), new FrameworkPropertyMetadata(false, OnIsEnabledPropertyChanged, OnIsEnabledPropertyCoerce));
}
private static void OnIsEnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var isEnabled = (bool)e.NewValue;
}
private static object OnIsEnabledPropertyCoerce(DependencyObject d, object baseValue)
{
var valueSource = DependencyPropertyHelper.GetValueSource(d, PipeControl.IsEnabledProperty);
var pipeContorl = d as PipeControl;
if (pipeContorl == null) return baseValue;
return (bool)baseValue && pipeContorl.IsMyPipe;
}
XAML:
<Grid IsEnabled="{Binding IsMyCondition , Mode=OneWay}">
<game:PipeControl Grid.Row="2" />
<game:PipeControl Grid.Row="2" Grid.Column="1" />
</Grid>
每个IsMyCondition改变OnIsEnabledPropertyCoerce被称为在每个PipeContorl时间, OnIsEnabledPropertyChanged不会被调用, 的ValueSource在OnIsEnabledProerty迫使是 “默认”(显示强迫总是得到默认的假值)。
我必须在其中我需要使用继承, 我预计值来源是“继承”的方式错过了一些 和OnIsEnabledPropertyChanged被调用。
UIElement有一个虚拟属性IsEnabledCore,它应该(?)用于强制IsEnabled属性。例如,Button或MenuItem根据CanExecute属性强制使用IsEnabled属性。 在您的自定义控制,您可以重写属性为:
protected override bool IsEnabledCore
{
get
{
return (base.IsEnabledCore && IsMyPipe);
}
}
最重要的事情就是打电话CoerceValue当任何属性(例如IsMyPipe)对其中的IsEnabled依赖的变化。
所以自定义控件的实现将是:
static PipeControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PipeControl), new FrameworkPropertyMetadata(typeof(PipeControl)));
}
public bool IsMyPipe
{
get { return (bool)GetValue(IsMyPipeProperty); }
set { SetValue(IsMyPipeProperty, value); }
}
public static readonly DependencyProperty IsMyPipeProperty =
DependencyProperty.Register(
"IsMyPipe",
typeof(bool),
typeof(UIElement),
new PropertyMetadata(
true,
new PropertyChangedCallback(OnIsMyPipeChanged)));
private static void OnIsMyPipeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
d.CoerceValue(UIElement.IsEnabledProperty);
}
希望这会有所帮助,并在解决方案的任何意见都欢迎。
阿德南的回答以上,而这样的回答:
How can I add logic to an existing dependency-property callback?
我由一个完整的答案。
CS:
static PipeControl()
{
PipeControl.IsEnabledProperty.OverrideMetadata(typeof(PipeControl), new UIPropertyMetadata(new PropertyChangedCallback(OnIsEnabledPropertyChanged)));
}
private static void OnIsEnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var isEnabled = (bool)e.NewValue;
}
protected override bool IsEnabledCore
{
get
{
return (base.IsEnabledCore && IsMyPipe);
}
}
IsEnabledCore返回值的回调,所以强制那里发生, 然后回调。
仅供参考,设置本地默认值似乎覆盖继承的,因此如果超驰继承 属性的元数据做螺母给一个默认的本地值,就像这样:
PipeControl.IsEnabledProperty.OverrideMetadata(typeof(PipeControl), new UIPropertyMetadata(false,new PropertyChangedCallback(OnIsEnabledPropertyChanged)));
除了
,如果你只需要要添加强制逻辑,您可以重写IsEnabledCore, ,而对IsEnabledProperty的元数据不做任何其他操作。
你说你不应该给一个默认的本地值,但是然后你在'new UIPropertyMetadata中设置'false'作为默认值(false, ...)'。我不理解超载或误解你的话吗? – 2016-10-05 01:32:01
我不确定,这段时间很难记住...... 在此依赖项对象中设置的默认值将成为它使用的默认值。并会覆盖默认值。 也许我不应该注意不要使用继承的值。我相信这是'真' – 2016-10-05 10:52:06
我会稍后再检查一下,10x – 2013-04-10 15:38:08
这很棒,但还有一件事,我仍然希望在PipeControl的IsEnabledProperty更改时得到通知,并从那里强制值。 我可以做到这一点与出一个不同的通知,如IsMyPipe的回调通知 – 2013-04-10 18:05:04