WPF - 脱节的控件需要通信

发布于 2024-10-02 07:24:51 字数 1459 浏览 0 评论 0原文

TLDR版本: 我需要找到一种方法来实现某种“消息中心”,其中任何控件都可以注册以接收来自其他控件的消息,而无需知道这些消息来自何处(或者它可以知道,只要它不意味着任何额外的信息)为我工作)。在输入整个内容后,我想我已经帮助自己实现了我所追求的目标,但是如果您可以推荐一些预先打包的解决方案,那就太好了!


因此,我正在研究这个项目,用户可以在其中进行一些选择并(或多或少)布局页面。不过,规则非常严格。在每一步中,他们都会获得有限数量的更改页面的方法。将其视为模板系统。

有多个接口: ITemplate、IContentArea 和 ISpecificControl 每个模板都有一定数量的内容区域。每个 ContentArea 恰好具有三个特定控件。

它们被合成在一起,就像这张粗略的图画: My Terrible Examples

浅紫色大框是模板。 黄色、粉色和棕色框是 IContentArea 的不同具体类型。 绿色、浅蓝色和深紫色框是 ISpecificControl 的不同具体类型。

这些接口的每个具体实现都将具有一些我希望用户能够设置的公共属性。

例如: 绿色框可能允许您设置字体大小和字体颜色。 浅蓝色框可能允许您设置背景颜色。 深紫色框可能允许您设置图像大小和边距。 黄色、粉色和棕色框可让您选择要使用的三个特定控件。 大的浅紫色框允许您选择内容区域的布局方式(有些可能只有两个或三个,也许它们按对角线排列)。

我创建了一个自定义属性,可以将其应用于 ViewModel 中的属性,将它们标记为符合用户更改的条件,并且我留出了一些空间来动态添加设置控件。这个想法是用户一次只能编辑一个项目。当他们选择它时,我将使用反射来检查控件的 ViewModel 的公共属性,并找到所有标记有可编辑属性的属性,查看它们的类型,并动态生成控件来编辑它们(当然,使用绑定) )。我们将其称为“设置向导”。

所以问题实际上有两个方面:

第一:您建议我如何限制用户一次只能选择一个框?显然我需要某种应用程序范围的事件或消息传递。那到底会采取什么形式呢?我如何注册我的“SettingsWizard”来接收这些消息。我觉得这将是一件非常简单的事情,但我忽略了它,因为它感觉不正确或不干净。

任何让这些控件之一发出一条消息说“嘿,我是最后一个被点击的。如果选择了其他人,那么现在你没有被选中”的任何操作都可以解决问题,只要接收控件不必知道消息来自哪里。

我正在考虑某种静态“消息中心”,其中创建每个控件时,它会使用定义的接口注册要传递的消息(在其构造函数中),并且任何控件都能够向消息中心发送消息,然后消息中心将把它传递下去。听起来对吗?我觉得这种性质的东西已经存在了。就像 Prism 中的功能一样(但我真的不需要任何其他功能)。

第二:我如何让我的“SettingsWizard”知道他有一个需要显示设置的新项目?据推测,第一项的解决方案也可以用于解决这一问题。这只是一种不同类型的通知。

TLDR Version:
I need to find a way to implement some sort of "MessageCenter" where any control can register to receive messages from other controls, without knowing where those messages are coming from (or it can know, so long as it doesn't mean any extra work for me). After typing out this whole thing, I think I've helped myself come to the realization of what I'm after, but if you can recommend some pre-packaged solutions, that'd be great!


So, I'm working on this project where the user gets to make some selections and (more-or-less) layout a page. The rules are very strict, though. At every step, they are given a limited number of ways in which they can alter the page. Think of it as a templating system.

There are a number of interfaces:
ITemplate, IContentArea, and ISpecificControl
Each Template has some number of content areas. Each ContentArea has exactly three specific controls.

They get composited together something like this crude drawing:
My Terrible Example

The big light purple-ish box is the template.
The yellow, pink, and brown boxes are different concrete types of IContentArea.
The green, light blue, and dark purple boxes are different concrete types of ISpecificControl.

Each concrete implementation of these interfaces will have some number of public properties that I would like the user to be able to set.

For instance:
Green boxes might let you set the font size and font color.
Light blue boxes might let you set the background color.
Dark purple boxes might let you set the image size and margin.
Yellow, pink, and brown boxes let you pick which three specific controls you want to use.
The big light purple-ish box lets you choose how the content areas are laid out (some might have only two or three, maybe they're arranged in a diagonal).

I've made a custom attribute that I can apply to properties in the ViewModel that marks them as eligible for user-changes, and I've set aside some space to dynamically add settings controls. The idea is that the user can only edit EXACTLY ONE item at a time. When they select it, I'll use reflection to examine the public properties of the control's ViewModel and find all the properties that are marked with the editable attribute, look at their types, and dynamically generate controls to edit them (with bindings, of course). We'll call this the "SettingsWizard."

So the problem is really two-fold:

1st: How would you recommend I limit the user to only selecting a SINGLE box at a time? Clearly I need some sort of application-wide event or messaging. What form would that take exactly? And how would I register my "SettingsWizard" to pick up on these messages. I feel like this is going to be something really simple, but I'm overlooking it because it doesn't feel right, or clean.

Anything that let one of these controls send out a message that says, "Hey, I'm the last one to get clicked on. If anyone else was selected, now you're not," would solve the problem, so long as the receiving controls didn't have to know about where the message was coming from.

I was thinking some sort of static "MessageCenter" where when each control is created it registers to be passed messages (in it's constructor) using a defined interface, and any control has the ability to send out a message to the MessageCenter, which would then pass it along. Does that sound about right? I feel like something of this nature already exists. Like the features in Prism (but I don't really have the need for any of the rest of the features).

2nd: How would I let my "SettingsWizard" know that he's got a new item he needs to display settings for? Presumably, a solution for the first item can also be used to solve this one. It's just a different kind of notification.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪异←思 2024-10-09 07:24:51

根据您的 TLDR 段落,我建议您查看 事件聚合器 模式。如果您正在寻找现有的实现,您可以查看 Prism 的。我认为 Prism 的设计有点过度,之前已经发布了更简单的实现

Based on your TLDR paragraph, I'd recommend taking a look at the event aggregator pattern. If you're looking for an existing implementation, you could take a look at Prism's. I think Prism's is a little over-engineered and have previously posted a simpler implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文