WPF control inheritance - wpf

I've read in a blog the following sentence:
The first rule of WPF:
Avoid control inheritance.
I've seen similar things in other places as well.
However, I fail to understand the logic.
Moreover, I see suggestions here in StackOverflow that involves inheriting WPF controls (see the replies to my previous question for example).
I would like to understand why (and if) control inheritance should be avoided.

WPF controls are "lookless". In other words, their look is separated from their behavior. More often than not, you actually want to customize the look - not the behavior. Unlike the world of Winforms, this does not require you to inherit a new control and override rendering logic. Instead, you set some properties on the control, resorting to overriding the template itself if you can't get the look you want from other properties.
Note that "avoid" means just that. Avoid inheritance if you can. In cases where you need to modify behavior, inheritance may well be the best option.

The blog from the link also states in the end that:
"With Styles, Templates, Decorators and attached properties and behaviors you can accomplish most of the things that you used to have to roll a new control for."
That is true. However, were it always true, the wpftoolkit team wouldn't have made their DataGrid as a subclass of MultiSelector.
Judge each case separately, I would say. Also check this answer.

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.

Use of Behavior in WPF MVVM?

I am new to WPF MVVM .. Anybody clear the usage of the Behaviors in MVVM application in WPF?. Why we should go for Behavior even we have Method action in WPF MVVM ?
A Behavior is the thing you attach to an element and specifies when the application should respond.
The Action is attached to the behavior and defines what the application should do when the behavior is triggered.
From this article:
At a glance, a behavior looks similar to an action: a self-contained
unit of functionality. The main difference is that actions expect to
be invoked, and when invoked, they will perform some operation. A
behavior does not have the concept of invocation; instead, it acts
more as an add-on to an object: optional functionality that can be
attached to an object if desired. It may do certain things in response
to stimulus from the environment, but there is no guarantee that the
user can control what this stimulus is: it is up to the behavior
author to determine what can and cannot be customized.
And from this article:
Behaviors let you encapsulate multiple related or dependent activities
plus state in a single reusable unit.
I highly recommend reading Introduction to Attached Behaviors in WPF that demonstrates:
What is attached behavior
What are it's alternatives
It's advantages compared to alternative solutions to similar problems
The idea is that you set an attached property on an element so that you can gain access to the element from the class that exposes the attached property. Once that class has access to the element, it can hook events on it and, in response to those events firing, make the element do things that it normally would not do. It is a very convenient alternative to creating and using subclasses, and is very XAML-friendly.
Conclusion from the above article:
Hooking an event on an object and doing something when it fires is
certainly not a breakthrough innovation, by any stretch of the
imagination. In that sense, attached behaviors are just another way to
do the same old thing. However, the importance of this technique is
that it has a name, which is probably the most important aspect of any
design pattern. In addition, you can create attached behaviors and
apply them to any element without having to modify any other part of
the system. It is a clean solution to the problem raised by Pascal
Binggeli, and many, many other problems. It's a very useful tool to
have in your toolbox.
In MVVM you may need to call methods from the View if your ViewModel exposes methods, not commands. Behaviors allow for this.
You state "we have Method action in WPF MVVM", but as far as I know "method action" is not part of WPF. If you are using a helper MVVM library, it may provide "method action" that could encapsulate methods in commands. In such a case, behaviors are not required for the MVVM pattern using methods.
Note, though, that behaviors have other uses outside of MVVM.

Why is TriggerAction internal?

Is there ans good reason why the TriggerEvent class usd in EventTriggers is implemented internal? I can find 3 implementations of this abstract base Claas. One to play a sound and two different actions regarding storyboards. What if I want to have a "SendEmail" action? Is more a hypothetical question. I don't have n actual application for it. I just noticed it and was wondering why it is implemented this way. To me it would be logical to derive my own action and just use it in the event trigger (an interface would be even better). Am I missing a point here?
Regards!
I doubt that you can do anything with those classes, use Interactivity from the Blend SDK instead, which provides classes (TriggerAction<T> for example) that can be sub-classed.
Edit: Somehow this is only found in the Silverlight documentation of the class:
TriggerAction exists in Silverlight for WPF compatibility. TriggerAction is not intended to be derived from as a base for other trigger implementations; the entire Triggers syntax is a discouraged technique in Silverlight 4. For more information, see Remarks in EventTrigger, or Customizing the Appearance of an Existing Control by Using a ControlTemplate.
Still no reason though.

Pros and cons of having a WPF specifics in the view model

I'm having trouble deciding what to think about this piece of code:
public SolidColorBrush Brush
{
get { return IsValid ? _validItemBrush : _invalidItemBrush; }
}
It is part of a view model in my current project and as you can imagine, the Brush will be bound to some text elements in the UI, to indicate (in-)validity of other pieces of data, in an otherwise fairly simple and straightforward dialog.
The proponents of this piece of code say that since we're using WPF, we might as well allow for some simple WPF specific constructs in the view model.
The opponents say that this violates Separation of Concerns, as it clearly dictates style which should be taken care of solely by the view.
Please share your arguments, and if you're not happy with the code above, please share your ideas around alternative solutions. (I'm particularly interested in what you have to say about using DataTemplates).
Is it possible that there is one solution that could be considered best practice?
Personally, I would have the two brushes be defined in XAML, and have the controls that use them switch brushes (in xaml) based on the IsValid property. This could be done very easily with DataTriggers, or even a single IValueConverter - the converter could take 2 brushes and a boolean and swap between them fairly easily.
This keeps the business logic presentation-neutral - a "Brush" is very specific to a specific form of presentation, and a pure View choice. Hard-coding this into the ViewModel violates the single responsibility principle as well as is not a clean separation of concerns.
I would very much keep this in the View, and switch based on the IsValid (bound) property that is ViewModel specific.
While there are circumstances where I might use WPF constructs in the view model, this isn't one of them. Here's why:
It's harder to change. If you define brushes as resources and use them in styles, changing your application's color scheme can simply be a matter of loading a different resource dictionary. If you hard-code color values in your view models, you have a lot of different things to change if it turns out your end users need different colors.
It's harder to test. If you want to write a unit test that checks to see if a property is returning the right brush, you have to create a brush in your unit test and compare the values of the two, since it's a reference type.
In many, maybe even most cases, it doesn't make the code simpler or easier to maintain. You're pretty likely to already be using a style (assuming that you are conversant with styles), since they make just about everything in WPF easier. Binding IsValid to brush colors is just a matter of adding a DataTrigger to a style. Which is where anyone maintaining this code would expect to find it.
There are certainly times when I do use WPF constructs in the view model - for instance, long ago stopped wondering if it was problem if a view model exposed a property of type Visibility. Note that none of the above concerns apply to that case.
In cases like yours where it's purely aesthetic I use Triggers or the Visual State Manager to change colors.
Sometimes I do use colors in my ViewModels, but only if its part of my software spec (e.g., the color of the chart displaying a patient's CO2 depends on localization). In that case, I use a Color struct bound property, allowing the View to use the Color for a SolidColorBrush, a GradientStop, or whatever it wants. I initially used a string in #AARRGGBB format to completely remove the WPF dependency but my more seasoned co-workers didn't like that.

Interactivity.Behavior<T> vs attached properties

I'm trying to find some differences between these approaches. Is there any situation where behaviors are used and the same functionality could not be done with attached properties?
No. Behaviors are basically just a much nicer abstraction on top of attached properties.
By using Behavior<T>, you gain access to the AssociatedObject directly, as well as the ability to attach and detach the behavior, easily, at runtime.
You could do this with attached properties, but it would require adding a lot of extra plumbing.
I tend to use Behaviors to add functionality which makes visible changes. Whereas I use attached properties to add additional information to an object which is subsequently used by other objects.
E.g. Grid.Row makes a good attached property, as it's used by the Grid and not the target. On the other hand, AutoCorrect would make a good behaviour, as this will make visible changes on the object.
Behaviors are based on attached properties. That means if you can't find specific behavior - you write your own, either based on behaviors framework provided by Blend or by creating your own AP...
I always thought that behaviors are great evidence of attached properties power. Just incredible what you can get with them.
This is not the answer. But the best explanation I can find on this topic
https://web.archive.org/web/20180208143035/http://briannoyesblog.azurewebsites.net/2012/12/20/attached-behaviors-vs-attached-properties-vs-blend-behaviors/
Brian Noyes in his articles clearly describes the differences between each of the concepts.

Resources