【问题标题】:Is there an event that fires when a binding has been set on a property?在属性上设置绑定时是否会触发事件?
【发布时间】:2012-06-26 08:19:17
【问题描述】:

我遇到了一个问题,我需要了解对我的对象的依赖属性进行的所有绑定。 目前,每当我的数据上下文发生变化时,我都会迭代依赖属性,并寻找绑定表达式。但我发现在某些情况下(TabControls),数据上下文似乎是首先设置的,然后是来自 XAML 的绑定。

那么,有没有一种方法可以检测应用到我的依赖属性之一的绑定?

【问题讨论】:

  • 解释起来有点复杂,但基本上数据上下文的对象(帮助可视化另一个类的数据的帮助类)知道这个控件正在呈现一个编辑界面存储在绑定表达式路径中指定的属性中的对象。

标签: c# .net wpf xaml


【解决方案1】:

假设您在 UserControl 中,您应该能够为此使用Loaded 事件。当“元素布局、渲染并准备好进行交互”时触发该事件。我只能假设这意味着绑定已经完成。

然后,您可以在 Loaded 事件处理程序中告诉您的数据上下文您正在绑定到它。

如果您希望数据上下文发生变化,您还需要将其与 DataContextChanged 事件处理程序结合使用。

【讨论】:

  • 感谢您理解我的问题。这确实是我一直在寻找的!我刚刚检查过,您的假设似乎成立。谢谢
  • 实际上,每当从可视化树中加载/卸载元素时都会调用LoadedUnloaded,并且在该元素的生命周期中可能会发生很多次(例如,主题更改可能会导致要重新加载的元素)。
  • 你当然是正确的@Grx70 - 当我写这个答案时我还很年轻,没有经验;-)我现在已经删除了那句话。
  • 当 Loaded 事件处理程序可能足够时使用 DataContextChanged 事件是不好的做法吗?
【解决方案2】:

我假设您使用私有静态 DataContextChanged 事件来知道您的数据上下文何时正确更改

这是我的一些代码 这就是我的工作

 public static readonly DependencyProperty ApplicationDataContextProperty =
            DependencyProperty.Register("ApplicationDataContext",
            typeof(Object),
            typeof(MyControl),
            new PropertyMetadata(MyControl_DataContextChanged));

// my constructor

        public MyControl()
        {

                InitializeComponent();

                if (!DesignerProperties.GetIsInDesignMode(new DependencyObject()))
                {
                    SetBinding(ApplicationDataContextProperty, new Binding());
                }

        }

// my event
        private static void MyControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {

                MyControl thisControl = sender as MyControl
                if (thisControl != null)
                {
                    INotifyPropertyChanged propertyChanged;
                    propertyChanged = e.OldValue as INotifyPropertyChanged;
                    if (propertyChanged != null)
                        propertyChanged.PropertyChanged -= thisControl.propertyChanged_PropertyChanged;


                    propertyChanged = e.NewValue as INotifyPropertyChanged;
                    if (propertyChanged != null)
                        propertyChanged.PropertyChanged += thisControl.propertyChanged_PropertyChanged;
                }

        }

// my 2e event
        void propertyChanged_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {

                if (e.PropertyName == "ListWithUsers")
                    LoadGrid();


        }

【讨论】:

  • 是的,我正在使用 DataContextChanged += 事件处理程序。我在控件的构造函数中的 InitializeComponent() 之前执行此操作。在 OnDataContextChanged 内部,它为明确绑定的绑定表达式返回 null(绑定在视觉上起作用)。但显然还没有被分配。
  • 如果我只是简单地改变数据上下文,那么由于控件已经被初始化,那么绑定表达式完美返回。
  • 嗯...知道数据上下文已更改如何帮助我检测绑定何时应用于我的对象?
  • JoshG 因为当绑定被应用时,数据上下文将会改变。
【解决方案3】:

尝试在关键绑定上使用NotifyOnSourceUpdated

http://msdn.microsoft.com/en-us/library/system.windows.data.binding.notifyonsourceupdated.aspx

或者您也可以使用 PresentationTraceSources 在输出窗口中获取详细的绑定信息

例如

<TextBlock Text="{Binding Name, PresentationTraceSources.TraceLevel=High}" />

【讨论】:

    【解决方案4】:

    当属性改变时引发事件正是 INotifyPropertyChanged 所做的。实现 INotifyPropertyChanged 需要一个成员,那就是 PropertyChanged 事件

    样品和更多细节:Raise an event whenever a property's value changed?

    【讨论】:

    • 我不想知道属性何时发生变化。我想知道绑定何时连接到属性。我不相信您的解决方案可以做到这一点?连接绑定可能不会更改该属性。即 value = null,有绑定,value 仍然 = null。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    相关资源
    最近更新 更多