Inheriting styles in custom WPF controls - wpf

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.

Related

Problems writing too much custom controls in WPF

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.

Subclassing WPF control themes, why not only PARTIAL subclass

So much reading, and so much about inheritance, I can't find any direct answers, so here goes.
If you have a base-class derived to do certain things, look or act a certain way, you can subclass it and get all the functionality of the parent class with only slightly modified differential. The same does not appear to be the same for working with WPF Themes... more specifically, the combobox control (similar issues with textbox, but that's obviously less complex).
By looking at the Control Template Examples, they discuss the entire structure of it, the borders, backgrounds, glyphs, actions, properties, etc.
If the ONLY thing I want to do with a combobox is to change the border of it to Red if there is an error in it, it appears, I have to basically redefine the entire thing and somehow put in my custom trigger setting / color to be implemented.
Somewhat similar is that of the textbox control and how its created. It has the named control when trying to nuts around with the background color... you can't just say... background = some static brush value.
What shortcuts are out there to only allow overriding these small elements without having to re-create the entire template control. I can just imagine what would go on with grids, tabbed controls, and others that could get extremely messed up if you miss one simple thing.
I also see that some controls are made up of OTHER Control.Templates, so how might I be able to attach to changing the property setting on just the single element of the control template... Such as the combobox has the control template for the Toggle Button. From that, it has a border via x:Name="Border" and I want to change THAT element within a derived style.
Thanks
I might not understand your question here. But from what i get is:
Yes you can't partially implement Templates, in fact i wouldn't know how this could be possible. But, if you want to change certain things, you can of course do that. You can create Styles, Templates, Brushes etc. as DependencyProperties and use TemplateBinding to bind to them, on the given child control.
Remember that WPF allows always to change the template on the fly. if we could partially change the template this would might hurt performance or could get messy and complicated. Still, you can do that using ContentControls and TemplateBinding or simply Triggers.
For my custom controls, which might contain multiple part sub controls, i usually add a style for them. For example, a custom ComboBox would contain a ToggleButtonStyle.
One thing that would be nice though, would be to add control template triggers without the need to reimplement the template.

Do I have to create a custom control as lookless?

I am creating a custom control derived from the one of the Standard WPF controls. The control has several constituent parts,and I am only modifying one of those parts.
Here's my question: If I am modifying only one part of a control, do I have to declare the control as lookless and reproduce the entire control template for the modified control in Generic.xaml, or can I omit the lookless declaration (found in the static constructor provided by Visual Studio) and simply modify the control template for the part I am extending?
I have tried the latter approach, and my control template is being ignored. I would like to get confirmation before I reproduce the entire control template, since what I am extending is the WPF Calendar. Thanks for your help.
It sounds like your best bet is to paste the entire template and modify the parts you need, although you didn't say exactly what you want to do or post any code.
Obviously if what you want to change about the calendar has a property you can modify in xaml, then that is easier. The opposite extreme would be to create a custom control (subclass).
I wanted to change the color or the ComboBox arrow the other day and the easiest way to do that was to past the entire template into a style and apply as needed, after changing one single part of the template (the arrow color, of course). There is no exposed DP to change for this and I didn't need anything more complicated than that.
HTH,
Berryl
The declaration that's generated for you by default is simply allowing for a default implicit Style to be defined for your control instead of just taking on the default Style of the base type.
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));
What makes a control lookless isn't any specific declaration but rather it's definition in a code file which will then have some ControlTemplate applied to it at runtime. The alternative is the UserControl style of declaring a XAML+code-behind class which compiles into a single class with both UI and logic.
A simple example: Button is not the thing you see on the screen and click on; Button is a control that can take a single piece of Content and translate a user click into a Click event or Command call. What you see on the screen is just a visual template on top of Button's inherent behavior and state.

Difference between styles and control templates

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.

Encapsulating and customizing a third party WPF control

I'm interested in customizing a 3rd party control, such as Telerik's RadGridView, as a standalone control, for example adding New Row and Delete Row buttons above the grid, yet still supporting XAML manipulation of the internals of the control by the window upon which my control exists (i.e. for the window to add its own style to a column of the grid).
Is there a way to add the buttons, etc. with templates? Styles?
My current "solution" is to inherit from the RadGridView, but I'm stuck on how to add the features I need.
Thanks!
My suggestion is to use composition over inheritance.
You can create your own control (UserControl should do the work). Then you can define the layout (may be in Grid panel): buttons on the top, RadGridView bellow them, etc. For custom column styling you can use DynamicResource trick. Set the styles of the columns you want to modified with DynamicResource. This way when the control is added to the logical(visual) tree; WPF will walk up the control tree and find appropriate resource. This way in each window/page resources you can define the different resource.
Another idea that come to my mind is that you can extract the buttons as a separate control. The only reference that they will need will be RadGridView and you can use binding with element name to provide it.
I would go the custom UserControl route instead of inheritance route. Styling and theming work strangely when you're dealing w/sub-classes. Unless you're planning on duplicating and modifying Telerik's ControlTemplates and DataTemplates, it can get pretty hairy.

Resources