【问题标题】:How to Manage Event Subscriptions at run time [duplicate]如何在运行时管理事件订阅 [重复]
【发布时间】:2015-01-08 04:26:45
【问题描述】:

好的,感谢 cmets 和建议我已经修改了我的问题以更准确地反映我的需要。

我正在阅读 INotifyPropertyChanged 在 WPF 中的工作原理,以便我可以在另一种技术中实现它的一种混蛋,在这种技术中,每当我跟踪 UI 更改的属性时,我的 UI 都会收到通知(Unity 4.6)。

基本上我需要的是当代码中的属性发生更改时,XAML 如何管理 INotifyPropertyChanged 的​​数据绑定和事件

我有一个 Unity 项目,我需要知道我应该如何设置我的 UI 类来订阅通知 UI 上显示的属性发生更改的事件,并创建所有实例UI 上与要更新的属性关联的文本。我需要在运行时订阅事件,因为当我在编译时订阅它们时,当我在屏幕上显示该对象不为空的属性时,我会从为空的对象获取空引用异常。即具有我要显示的属性 Property1 的类 MyObject

var MyGameObject1 = new MyObject();
MyGameObject1.Property1 = "Bob";

我的二传手在哪里

public string Property1
{
get
{
return _property1;
}
set
{
_property1 = value;
NotifyPropertyChanged("Property1");
}
}
public event EventHandler<UnityPropertyChangedEventArgs>  PropertyChanged;

private void NotifyPropertyChanged(string propertyChanged)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new UnityPropertyChangedEventArgs(propertyChanged));
    }
}

如何让我的 UI 在运行时管理我通过文本显示的 UI 元素,并在其值更改时接收从其设置器触发的事件。

【问题讨论】:

  • 是的魔法。查看依赖属性管理器。
  • XAML 在任何绑定上侦听这些事件
  • 它本质上是一个 Observable 模式,发生一些变化,任何注册的监听器都会得到通知。这也可以在其他技术中完成(winforms 或任何基于事件的)。当 XAML 被解析并转换为 UI 时,就会设置诸如绑定之类的东西。我的问题是你需要这种魔法的技术是什么?
  • 它只是为了一个小小的团结游戏,信不信由你,我真的很喜欢这种模式,虽然我承认我不太了解它。
  • Spiked3 您是否有专门的文章或文档来设置这些物业经理。

标签: c#


【解决方案1】:

由于您想在基于 Unity 的环境中实现类似的功能,因此您最好提出一个专门解决该问题的问题。也就是说,要回答您的具体问题:

  1. “订阅 PropertyChanged 以注册更改的内容已经发生。”

WPF 订阅它。

  1. “它在哪里订阅它。如果在运行时,如何订阅?”

这取决于确切的上下文。在某些情况下,XAML 编译器可以生成订阅事件的代码。在其他情况下,这要到运行时才能完成,这是通过检查对象是否实现 INotifyPropertyChanged 并订阅事件来完成的。

  1. “这是通过 INotifyPropertyChanged 自动完成的。”

从某种意义上说,WPF 自动处理该接口提供的事件是自动的。接口本身不会导致这种情况自动发生。 IE。在其他情况下,简单地实现该接口不会导致同样的事情发生。

  1. “接下来,它如何知道 UI 上的哪个属性要更新,因为它只知道 PropertyName(据我所知)当事件被触发时,当订阅事件的任何内容接收到它时。”

在基于 XAML 的应用程序中,XAML 本身中存在引用特定属性的信息,将该属性绑定到某个 UI 元素(例如元素的属性、其样式等)。您没有展示任何 XAML,因此无法在您的示例中具体说明它是如何工作的。

【讨论】:

  • 好的,谢谢你的回答,我会用我的小统一项目作为示例代码抛出我当前的实现(真的应该首先这样做)
  • 所以再想一想,我认为我需要退后一步,看看 WPF 的 INotifyPropertyChanged 实现,看看像 WinForms 这样的技术如何与它进行所有绑定后面的代码?因为它与我的实际代码更相关?
  • @Oliver:Winforms 也有相当广泛的数据绑定模型。在其他框架中复制其或 WPF 的绑定模型将是一项重大任务,恕我直言,可能不值得。相反,您应该努力了解您正在使用的框架(Unity,对吗?),看看它是否可以用于数据绑定。如果那是“没什么”,那么除非您打算成为附加库的提供者以将该功能添加到 Unity,否则我只会根据需要手动实现绑定。
  • 感谢您的 cmets Peter,我想我会选择一个更温和的解决方案,它可以最大限度地减少手动更新 UI 的麻烦,而不是寻找一个详尽的解决方案。还在旅途中,我确实学到了很多东西,所以我总有发扬光大的地方。感谢您的回复
【解决方案2】:

有一个空对象,当它被设置时,我想在我的 UI“SelectedObject.Property1”上显示它的属性。

只需使用观察者模式——就这么简单。将“属性更新”事件添加到您的源模型类,并让您的 UI 类订阅该事件。

订阅 PropertyChanged 以注册更改的内容已经发生。

如果您查看 UI 绑定属性的“PropertyChanged”调用列表,您会注意到每个绑定的 XAML 属性都附加了一个“WeakEventListener”。弱事件侦听器可以附加到事件,而不会阻止对拥有该事件的对象进行垃圾收集。

它在哪里订阅它。如果在运行时,如何?

这是您进入框架内部的地方。基本思想是 UI 元素具有关联的数据上下文,并且当设置或更改数据上下文时,任何绑定都会订阅源事件。运行时存储 XAML 的可视化树,数据上下文沿可视化树继承。 (请注意,XAML 还支持 UI 间绑定,例如“ElementName”和“RelativeSource”,它们附加到可视树中的其他元素,而不是数据上下文。)

接下来,它如何知道 UI 上的哪个属性要更新,因为它只知道 PropertyName(据我所知)当事件被触发时,当订阅事件的任何东西接收到它时。

这不太对。绑定包含有关源和目标的信息。它实际上持有对源对象的引用,因此它可以在收到更改通知时使用属性名称检索值。

我看的越多,就越觉得魔法在某处与设置绑定和执行 UI 更新有关。

运行时处理管道,所以你看不到它。我认为关键是使用像 XAML“绑定”这样的中介对象,它订阅源上的事件,并根据需要更新目标。这样,源(视图模型)和目标(视图)对象就保持了它们的自主性——同样,解耦是观察者模式的关键。

【讨论】:

    猜你喜欢
    • 2022-01-08
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    相关资源
    最近更新 更多