绑定仅在调用事件时应用于源

时间:2015-01-14 23:48:47

标签: c# wpf binding dependency-properties

我有一个具有依赖项属性的自定义控件。在Dependency属性上调用SetValue时,除非在触发UI事件后调用SetValue,否则不会发生任何事情。看下面的例子,看看我的意思。

public static readonly DependencyProperty ItemDictionaryProperty = DependencyProperty.Register("ItemDictionary", typeof(Dictionary<string, Control>), typeof(ListBoxEx),
        new FrameworkPropertyMetadata(new Dictionary<string, Control>(),     FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender, OnItemDictionaryPropertyChanged));

    private Dictionary<string, Control> itemDictionary = new Dictionary<string, Control>();

    private static void OnItemDictionaryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var test = (ListBoxEx)d;
        test.ItemDictionary = (Dictionary<string, object>)e.NewValue;
       // test.GetBindingExpression(ItemDictionaryProperty).UpdateSource();
    }

    public override void EndInit()
    {
        itemDictionary.Clear();
        foreach (var item in this.Items)
            itemDictionary.Add((item as Control).Tag.ToString(), item as Control);

        this.ItemDictionary = itemDictionary; // This doesn't

        base.EndInit();
    }

    public Dictionary<string, Control> ItemDictionary
    {
        get { return (Dictionary<string, Control>)GetValue(ItemDictionaryProperty); }
        set  { SetValue(ItemDictionaryProperty, value); }
    }

    protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
    {
        itemDictionary.Clear();
        foreach (var item in this.Items)
            itemDictionary.Add((item as Control).Tag.ToString(), item as Control);

        ItemDictionary = itemDictionary; // This works
        base.OnMouseLeftButtonDown(e);
    }

ItemDictionary中更新EndInit时。绑定属性不会更新。 一旦我在事件方法中调用它,那么突然间我的更改会影响源。

我做了一点测试,看看我的绑定是否是EndInit创建的,但在我的viewmodels构造函数中将属性设置为null。因此,即使绑定有效,它也会调用OnItemDictionaryPropertyChanged。源中没有任何内容发生变化。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

我的猜测可能是应用程序生命周期问题。在使用ItemDictionaryProperty中的new Dictionary<string, Control>()设置FrameworkPropertyMetaData之前,可能会调用EndInit()。 EndInit()似乎只与控件的图形部分相关。 MSDN for ISupportInitialize.EndInit

尝试使用Loaded事件。 Info on MSDN