era*_*zap 2 wpf inheritance dependency-properties custom-controls
我需要我的控件从Grid类型的祖先那里继承UIElement.IsEnabledProperty(可以选择Window或其他任何我可以用来包装我的网格的元素)
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;
}
Run Code Online (Sandbox Code Playgroud)
XAML:
<Grid IsEnabled="{Binding IsMyCondition , Mode=OneWay}">
<game:PipeControl Grid.Row="2" />
<game:PipeControl Grid.Row="2" Grid.Column="1" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
每次IsMyCondition更改时,每个PipeContorl中都会调用一次OnIsEnabledPropertyCoerce,从不调用OnIsEnabledPropertyChanged,OnIsEnabledProerty Coerce中的ValueSource为“ Default”(显示Coerce始终获取默认的假值)。
我必须以需要使用继承的方式错过某些东西,我希望值源被“继承”,并调用OnIsEnabledPropertyChanged。
小智 5
UIElement具有一个虚拟属性IsEnabledCore,应使用该属性强制IsEnabled属性。例如,这就是Button或MenuItem强制IsEnabled属性取决于其CanExecute属性的方式。在自定义控件中,您可以按以下方式覆盖属性:
protected override bool IsEnabledCore
{
get
{
return ( base.IsEnabledCore && IsMyPipe );
}
}
Run Code Online (Sandbox Code Playgroud)
重要的是,当IsEnabled所依赖的任何属性(例如IsMyPipe)发生变化时,都要调用CoerceValue。
因此,自定义控件的实现将是:
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 );
}
Run Code Online (Sandbox Code Playgroud)
希望这会有所帮助,并且欢迎对该解决方案发表任何评论。