wpf - 如何在初始化期间使用混合行为的 DependencyProperties?

标签 wpf dependency-properties expression-blend

这里我有一个简单的混合行为。它有一个DependencyProperty,我想在OnAttached 的初始化期间对其执行一些操作。但我不能,因为该行为似乎在初始化之前就已经附加了!

用法:

<Button>
    <e:Interaction.Behaviors>
        <local:TestBehavior Test1="{Binding ValueOnViewModel}"/>
    </e:Interaction.Behaviors>
<Button>

定义:

class TestBehavior : Behavior<FrameworkObject>
{
    public static readonly DependencyProperty Test1Property
        = DependencyProperty.Register("Test1", typeof(int), typeof(TestBehavior),
        new PropertyMetadata(OnTest1Property_Changed));

    private static void OnTest1Property_Changed(DependencyObject sender,
        DependencyPropertyChangedEventArgs args)
    {
        // This gets called _after_ OnAttached!
    }

    public int Test1
    {
        get { return (int)GetValue(Test1Property); }
        set { SetValue(Test1Property, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        // No matter what Test1Property is bound to in XAML 'a' will be default
        // value because as this point the Behavior is attached, but not
        // initialized!
        int a = Test1;
    }
}

这让我觉得很奇怪。在这个简单的情况下,我可以通过在 OnTest1Property_Changed 而不是 OnAttached 中执行初始化来解决这个问题(尽管在静态上下文而不是实例上下文中存在轻微的不便)。

但是,如果我有一个相当不那么琐碎的具有多个属性的行为怎么办?在该行为的一些用法中,所有DP都可以被显式设置,而在其他情况下,可以仅设置一些DP,同时使用未显式设置的DP的默认值。我可以处理行为定义的所有 DP 的更改事件,但我无法知道客户端在 XAML 中显式设置了哪些 DP,因此我无法知道在初始化完成之前必须发生更改通知.

那么在这种不平凡的情况下,我如何才能知道行为的初始化何时完成呢?这看起来是一个如此明显的弱点,我只能假设我错过了一些明显的东西。

[更新]

根据 Sorskoot 的建议,我创建了这个简单的基类,我可以将其用作我的行为的基础。

public class BehaviorBase<T> : Behavior<T> where T : FrameworkElement
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += AssociatedObject_Loaded;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.Loaded -= AssociatedObject_Loaded;
    }

    protected virtual void OnLoaded()
    {

    }

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        OnLoaded();
    }
}

最佳答案

我建议在 OnAttached 方法中附加到 Loaded 事件,并在其中进行初始化。

 protected override void OnAttached()
 {
      base.OnAttached();

      base.AssociatedObject.Loaded += onloaded;
 }

 private void onloaded(object sender, RoutedEventArgs e)
 {
      int a = Test1;
      // Test1 should contain a value here. 
 }

关于wpf - 如何在初始化期间使用混合行为的 DependencyProperties?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16421090/

相关文章:

wpf - 绑定(bind)到自定义依赖属性 - 再次

xaml - 为什么我的 DependencyProperty 不可访问?

silverlight - 如何在 Silverlight 中使用 MVVM 根据绑定(bind)到的数据更改 DataGrid 的单元格?

silverlight-4.0 - Metro 风格的 Silverlight 应用程序

c# - 访问未通过 Blend 创建的对象

c# - 在 WPF 3D 中用圆柱体连接两个球体

c# - 使用 wpf mvvm 在运行时更改 URI 时,图像未在 UI 中更新

WPF:类似浏览器的撕裂

c# - 派生的 UserControl 未在 parent 更改 DependencyProperty 时得到通知

wpf - 如何获取Visual Studio 2013 Express的Blend