WPF - Disjointed Controls Need to Communicate - wpf

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:
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.

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.

Related

Benefits of Custom WPF Controls

I've thoroughly checked the custom controls topic, spent several hours looking into custom controls written by other people. I've written my own custom button, to feel it better. I've read all the google answers around the "why custom controls", "advanced custom controls examples" and such.
My question is, WHY?
Why would I (or anybody) go through 9 circles of hell to create his own custom control, when one can just adjust an existing control to his needs (using styles and templates). I actually didn't find any explanation on google, just tons of examples, mostly from people who sound even less educated than me.
I imagine there IS such need, when talking about some complicated DataGrid with, I don't know, every cell being a button or something (and still I believe I could do it with a regular DataGrid)... But I've not found anything more complex than a beautiful button. Is there nobody sharing a complicated code on the topic?
There are different levels of element customization in WPF, depending what class you extend from. Each has its own uses and is implemented differently. It is not clear from your question if you are asking about a specific type of control or about all of them in general. So, I will tell you what I think about different ones.
UIElement or FrameworkElement
Extending UIElement gives you the lowest level custom control where you have complete control over the layout and rendering. FrameworkElement is slightly higher level as it does most of the common layout stuff for you while also allowing you to override key parts of it. The main idea with these is that they do their own rendering rather than composing other elements together.
I have made a number of custom FrameworkElements over the years. One example is a ruler similar to one you might find in a program like Photoshop. It has a bunch of properties providing customization for how it is displayed as well as showing markers indicating mouse position relative to the ruler (and a number of other little optional features). I have used it in two different professional projects. I think the main benefit is that it is extremely easy to drop in and set properties/bindings on wherever desired. Build it once, use it over and over.
Control
Extending Control introduces the concept of compositing multiple elements/controls into one reusable component via control templates.
I have used this one less often, but still find it very valuable in the right circumstances. Again, the main benefit here is reusability. You create a control with properties that make sense for what you want to do, then hook up those properties to the properties of the controls in it's control template. Really, this is the same as applying a new template to an existing control, with the added feature of being able to define your own dependency properties. You also have the ability to perform custom logic in the control's code if you need to.
I may be misreading some of your text, but you seem to imply that making a custom control is considerably more difficult than making a control template for an existing control. I have found that the two are nearly identical in most cases using this approach, the only difference being whether you have a code behind you can use.
User Control
A user control is really only slightly different from a custom control practically speaking. Only, instead of defining a control template, you define the visual content directly.
This is probably the most common type of custom control. It is basically the standard method for making XAML based content in a WPF application. These can be reused like other controls, but are more suited for single use such as the content of a dialog or window or something else that is specific to a single application.
Some Other Control
You can also extend an existing control to add additional functionality to it. This way, you still get all the features the control offers and only have to implement the additional bit.
For example, I have a custom control called an AutoScrollRichTextBox that extends RichTextBox. So, it does everything a RichTextBox can do. It also has the ability to automatically scroll to the bottom when content is added to the text box (which it only does if the text box was already scrolled to the bottom before the addition content was added).
I could have implemented that feature as an attached property instead of an extension of the control (and maybe I should have), but it works, and I have used it in three different applications (as an output window and as a chat log). So, I am happy with it.
In the end, it really is just a matter of how self-contained, reusable, and easy to drop in you want a control to be. If there is already a control that does what you want, and you just want it to look different, then you should definitely use styles and templates to achieve that. However, if you want to make something that doesn't already exist, limiting yourself to using only styles and templates will make the implementation work harder and make the end result less reusable and more difficult to set up additional instances (unless all instances are identical).
The examples of making things like buttons that look different are not examples of what you should use a custom control for. They are just examples of how someone would go about making a custom control for the purpose of teaching the details of the process. If you actually want a customized button, just customize a button.

WPF, Control. Stack of values for dependency property

I've stuck with one pretty trivial problem (at first look).
Simplified version of my situation looks like this:
I want multiple Background(for example) colors to be applied to SAME Control and to be able to clear only some of them (by condition). WPF does not offer such capability, I can set only one value for each DP.
So, I want to apply Yellow then Green then Red colors successively to Control object and then be able to reset Red so that Control will be with Green background (on the other hand, reseting Green leaves background Red). Looks pretty simple, have you ever created such Decorator for Control? I believe DP internally use such behavior, but there are no public APIs for it.
Please, do not suggest using triggers or any other kinds of conditional DP setting, I really need to set multiple values for single DP and to be able to manage them
Its not a good idea to say "do not suggest" ... Anyway, Well its not possible, and WPF does not do this, what you might meant is the value precendence but this List is fixed, you can't just add another layer in between, for good reasons. The whole system relys on that. Otherwise you could not set one value and use triggers to override it and don't need to take care of resetting the value. Also animations, Style inheritence etc. wouldn't be possible if people start to mess with this list.
So you don't like the trigger idea ... Why? Its exactly for that.
Ok, if you don't like it, how about adding an attached property for Background1, Background2 etc. You also could make Background as an attached property and make it inheritable. You could make an attached behavior, listen to property changes and modify your Background color. You could use a MultiBinding or PriorityBinding.
Well alot of stuff is possible if the obvious solution is not desired :)

How to pop out a WPF control from the flow and bring it to the first plane

I have an application that present data in a summarized way. The structure of the view itself is not trivial, but not really complicated either (ie, a user control in a tems control, in a stackpanel,in a grid, etc). I want that when clicked the usercontrol pops out to the front plane and grows to show all the details (with an animation, like a plane flip or something alike).
Idealy, the user control should be duplicated so that the original one stays in place, and needs to stay in the application window boundaries. If modal, even better.
I'm looking for pointers on how to achieve this, not necessarily a detailed walkthrough. I'm not interested in commercial products, even if it means I need to reinvent the wheel. I had a look on many quite similar questions on SO, but haven't found anything useful so far.
Storyboard can get you the animation you need. Panel.ZIndex will allow you to set it on top of the other controls like you would in a web page. A sample of this with a Canvas can be found here: http://blogs.msdn.com/b/wpfsdk/archive/2006/06/13/controlling-zorder-using-the-zindex-property.aspx

Style a button to match the current theme for the expand/collapse button on a TreeView

As you know, the built-in themes all define styles for the standard controls such as the TreeView control. We're trying to create something that looks an awful lot like a TreeView but isn't actually one, nor is it a subclass of one. It just has parts that we want to look like one for consistency.
For instance, our control too has a selected item whose background we'd love to match to the appearance of the background for the selected item in a TreeView (or more accurately the TreeViewItem) for the current theme. (You can't simply use highlight color as the themes have nice gradient brushes and borders, not just a solid brush.) Same with our expand/collapse togglebuttons. We want them to look just like the ones used in a TreeView for the current theme. (i.e. Sometimes a triangle, sometimes a box with a '+' in it, etc.)
Now while we can simply rip open Expression and copy the styles ourselves (or at least the parts that we need), we'd have to do that for each and every theme that MS provides. Plus, that wouldn't handle newer themes. And in a purest standpoint, that's duplicate styling information which just sits wrong with me.
Also, if someone styles the actual TreeView(Item), we want to pick it up as well. Since the parts that we want to style are required parts of a TreeView, we feel pretty confident that they're in there somewhere style-wise.
Not even sure what I want to do is possible but if anyone knows, they're most likely here on SO!
Yet another question close to a month old without even a comment. Very odd for the SO community to not chime in at least once! Guess it's not possible.
Well, what we ended up doing was using 'Show Me The Template' (Google it) to get the templates for the part (we don't have Expression), then manually managing them ourselves instead of using the built-in styles. NOT at all what we wanted to do since we don't know of a way to get the nice gradients that are defined in the system already without duplicating them, but the end result does match perfectly so there's that. As such, this too is getting marked as the answer. I'll gladly change it if someone else actually gives me one that works (or is close enough! Just need something people! Feel like I'm posting in a vacuum here!

wpf / silverlight textbox filter design

I have a list that the user can filter in several ways. two of which lend themselves to combo boxes and two that need to accept user input. For example, one textbox allows the user to type in any part of a list item's description, and the dialog will only present items whose description contains the text entered.
It is a dialog 'picker' type of window, so space is at a premium. I'd like for the text boxes not to require a traditional label. Instead, when the dialog is first invoked, the label (ie, "Description") is grayed out, centered, and in italics. Maybe a tool tip to further make it obvious to the user what it's for. When the user starts to type, the faux label disappears and the entered text is normal left aligned text.
Does wpf / silverlight have any native support for doing something like this? I guess it could be a combination of styles and eventing. I'd rather not invent any wheels that might be out there (I got the idea specifically from looking at Tortoise' "Show Log" window, but I've seen it before).
Does anyone have any sample code they can share to do this? Or a an alternative idea that also saves space and simplifies the layout?
Cheers,
Berryl
Kevin Moore's InfoTextBox, which is part of his Bag-O-Tricks is the kind of thing I was looking for, almost exactly. This is also the 'watermark' (great name - I would have found this sooner if I had known that) text box from another post.

Resources