I am working on new WPF/MVVM project, where I see all most all controls are written for different needs, right from textbox to treeview. All are rewritten for simple need, for example, grid,stackpanel control are rewritten to add space between each item and textbox is rewritten to include label for it so that it has both label and text input are on itself.
My question : Is there any serious issue we would encounter because of this customization?
Already, I am seeing issues with aligning all controls, will i would see any more issues because of this?.
You should never create a custom or user control to add margins, a label to a TextBox, or a new ItemTemplate to a ListBox.
UserControls are for grouping frequently used combinations of controls into one reuseable control. An example may be a custom List-of-Values control that opens a dialog. This would be fine to implement as a UserControl.
Custom controls are good when a native control does not suit your needs. Say that you want to reimplement a DateTimePicker from scratch because the native one doesn't include milliseconds.
There are no serious issues as such, but you may find yourself maintaining all these controls for the next many years without there being a need to do so.
Settings Margins should be done in the View where you are using it, or on a Style in a ResourceDictionary.
This is of course only my opinion (and that of many others, I except), but if you find that the majority of your controls are 'customized' this way, you are doing it wrong.
Style and Templates rather than UserControls and custom controls.
The main issue is that you lose the ability to alter margins only in a single view. If you change your custom controls' inner paddings and margins, you will be changing all the views in your solution. If you use a style, you can always override it by defining a new style in the view, or by setting the property directly.
I inherited a project that uses a RadioButtonList which inherits from a ListBox. It was taken off the web (currently cannot find a link to), and contains RadioButtonList.cs (which contains six dependency properties) and RadioButtonList.xaml (which is just styles and control templates).
This control is used in over a hundred places. It causes problems because it is not a complete and professional control. Problems such as, focus issues, keyboard navigation, and so on. (See comments.)
After much research at different times over the last couple years, it seems that this control is really not necessary. All that is needed is to set the GroupName property on a group of radio-buttons. And, the only reason why a RadioButtonList control is used is to help with data-binding a list of options through the inherited ListBox.
1) Is this control really necessary? Is there a better way?
2) Is there a professional control, open-source or otherwise, that will allow me to get the benefits of data-binding without the headaches? (We use Infragistics and DevExpress, but I am not familiar with all the controls these suites offer.)
My Answers
1a) Is this control really necessary?
If you only need one list of radio buttons, then no this control is not necessary.
If your applicaton uses many lists of radio buttons, then yes this control is necessary.
If you use a list of radio buttons in different applications, then yes this control is probably necessary.
1b) Is there a better way?
I say that deriving from a ListBox, ItemsControl, or whatever then creating styles and templates is the only way to create this control; therefore, no there is no better way.
2) Is there a professional control...
Definitely, the ListBoxEdit with the RadioListBoxEditStyleSettings.
Comments Regarding Answers
All the answers indicate that creating a RadioButtonList control is not necessary. Yet, if you need more than a couple lists of radio buttons, by the time you create the styles and control templates and maybe data template, you will end up with a collection of code artifacts that can be called a radio-button-list-control. Therefore, in my opinion, a RadioButtonList is necessary.
Moreover, my understanding is a RadioButtonList was dropped in an early WPF CTP. Which I can understand, because of the limited need for such a control that can easily be created.
Comment Regarding Accepted Answer
2) Is there a professional control...
Definitely, the ListBoxEdit with the RadioListBoxEditStyleSettings.
Lastly Comment on Mike Strobel's Answer
The RadioButtonList that I have is the end-result of his answer. While I am good at creating custom-controls, I rather let third-party component makers, such as Infragistics and DevExpress, create and support a basic control like this one.
Is this control really necessary? Is there a better way?
As #lawc points out, no, it is not necessary. It may, however, be preferable, depending on what level of flexibility you desire. A reusable style is easy enough to create, but doing it "correctly" is a bit more involved than simply setting a custom ItemTemplate.
Using Styles
An ItemsControl in WPF will wrap its items in appropriate containers. Each of the selector controls in core WPF overrides the logic which determines whether an item is capable of serving as its own container, as well as the factory code which produces new item containers. A ListBox, for example, will wrap each of its items in a ListBoxItem (unless the item itself is already a ListBoxItem). The style applied to these containers can be set for the parent ItemsControl via the ItemContainerStyle property. This differs from the ItemTemplate property, which allows you to control the appearance of the item within the container. More specifically, it overrides the content template applied to the ContentPresenter within the container.
Since a RadioButton does not derive from ListBoxItem, simply setting the ItemTemplate will produce a list of RadioButton controls embedded within ListBoxItem controls, which means they will still have the same selection chrome normally associated with ListBox controls, and possibly some layout and focus oddities. This is probably not what you want.
Instead, override the ItemContainerStyle and use it to assign a custom ListBoxItem template which embeds a RadioButton. You can probably get away with not setting the GroupName property at all, which eliminates possible name collisions. Instead, just establish a two-way binding between the RadioButton.IsChecked property and the templated parent's ListBoxItem.IsSelected property.
In order to use this technique conveniently, one generally creates a Style resource (available application-wide) which can be applied to the appropriate ListBox instances, and which sets the ItemContainerStyle. Alternatively, you can make the container style available as a global resource and set that on your ListBox instances. Either way, you need to set a property.
Using a Custom Control
While WPF evangelists often recite the philosophy of preferring custom styles over custom controls, in practice this is not always convenient. You may find it more convenient to create a RadioButtonList which extends the ListBox control, and then give it a default style which automatically applies the custom style described above. This gets you out of manually assigning the list style or container style on every ListBox instance, but it's not a huge win.
But maybe you want a bit more control over the appearance of the RadioButton items. For instance, you may want to:
Adjust the margin around the "bullet" of each RadioButton item;
Adjust the vertical alignment of the bullets relative to the content;
Support both horizontal and vertical orientations;
Automatically disable the RadioButton content for items which are not selected.
Creating your own implementation, most likely derived from ListBox, allows you to add these features easily, even after you are already using your radio list across your application. This could be done with the technique above too, though it may require an attached behavior or some attached properties, in which case you end up with a somewhat fragmented design.
Third-Party Solutions
Is there a professional control, open-source or otherwise, that will allow me to get the benefits of data-binding without the headaches?
This is not an uncommon use case, and I have no doubt there are some implementations floating around. Some may be in open source frameworks, and some may be extracted from open source applications. As for third-party implementations, I do know that Actipro ships a RadioButtonList in their Shared WPF library, which is included with all of their WPF components. When last I checked, it was not available on its own. It does, however, support all of the additional features I listed above.
I can only tell you that DevExpress uses a ListBoxEdit with a RadioListBoxEditStyleSettings to represent a group of RadioButtons. Practically it is the same as your control you are using, but i think it provides better functionality and is well tested. A RadioButton is not provided by DevExpress and in my application i use the Default RadionButton-Control provided by WPF/Silverlight.
You use the RadioListBoxEdit of DevExpress as follows:
<dxe:ListBoxEdit SelectedItem={Binding CheckItem, Mode=TwoWay}>
<dxe:ListBoxEdit.StyleSettings>
<dxe:RadioListBoxEditStyleSettings />
</dxe:ListBoxEdit.StyleSettings>
</dxe:ListBoxEdit>
More information about the ListBoxEdit of DevExpress can be found here
In my opinion you don't need this control.
You can simply use .Net ListBox to achieve all your existing functionality.
Using ListBox.ItemsSource you can data bind your options collection
Specify ListBox.ItemTemplate containing the RadioButton, in this template you can data bind your view model property to RadioButton.GroupName
IMHO, a control deriving from ItemsControl would be the cleanest approach.
Then you probably would override
IsItemItsOwnContainerOverride() with return item is RadioButton;
GetContainerForItemOverride() to return a new RadioButton() for each item and
PrepareContainerForItemOverride() to set up binding of ToggleButton.IsCheckedProperty and ContentControl.ContentProperty.
While these parts are just boilerplate code, some more efforts may lie in the implementation of the keyboard behavior.
Is there a way to globally change the validation template? I need to make a couple of minor tweaks to it and I don't want to have to edit every single template.
To my knowledge, no there isn't. If you're talking about the red border and the sliding popup around TextBoxes, ComboBoxes, etc. They are coded into each control's own ControlTemplate and not referenced (like a Behavior) from a common source. You'd have to redefine the implicit styles for all used basic control, or write your own validation behavior which is independent of the control (e.g. put a red border around it and write some text too) and attach it to every control you use.
I have a datagrid, and certain columns need to contain text that is linked to a detail window. So, in order to make it a bit easier on myself, I created a UserControl that is basically a Button with a control template that contains a TextBlock (I could have done this a number of other ways, I know, but I figured the button already exposes a Click event, so why not?). Things are getting a bit hairy, though, when it comes to styling: I'd like to give the text a "hyperlink" sort of format--blue text, underlined--so that it's clear they are links (also, so that they resemble to format in the legacy WinForms application I'm re-implementing). But I would also like to be able to style the text--ideally, it should grab things like text color if text color is set in a style on the parent cell.
Basically, is there an easy way to implement a custom UserControl that will a) grab styles from a parent element and b) apply its default styles in a low-priority way, i.e. only apply a specific style if there's not already one set from the parent? I know I can pass the parent's style manually through a binding, but I was wondering if there was an easier way.
It sounds like you need to create a true Control or ContentControl implementation for this, so that you can override the true styles and templates.
UserControls are not really stylable, unless you start somehow creating custom properties for binding Styles.. but none of that will be implicit.
I'd like to know what the differences between an Style (for a control) and a control template are.
Best regards,
Gonzalo
A style controls the individual properties of a control. For instance, a button style can say, "For every button, use this background." A style is changing a single property on a control.
A control template is actually handling how the control displays its bound data. Instead of saying, "I want to override a control's properties," you are assembling together other smaller controls into a single control that can present different views of the bound data.
Previously in WinForms, if you wanted to write a custom list box (say that had an icon next to each item), you had to inherit from the ListView control and override the painting methods. This involved a ton of experimentation - huge pain. With WPF templates, you can use XAML to construct smaller controls together and bind them to different properties of the parent control. You are actually defining the Visual Tree for the control.
See this article for an in-depth explanation by Charles Petzold.
Imagine your control is a house.
A Style is conceptually similar to putting down a new carpet and painting the walls. The house itself is still the same but its outward appearance is different.
A ControlTemplate is the equivalent of knocking down a wall or adding a conservatory. The actual structure of the house has changed.
Use a Style when you want to change the outward appearance of the control E.G. it's background colour or the thickness of it's border.
Use a ControlTemplate when you need to change the underlying structure of the control. This is useful when you want to change the layout of certain aspects of a control. A good example is in this article which re-templates a TabControl to look like the navigator from Microsoft Outlook.