RichK
RichK

Reputation: 11871

Overriding a property within a ControlTemplate

I have a very large ControlTemplate (200+ lines) with many nested controls inside. I need to reuse this template with a small change to one of these nested controls (visibility of a checkbox). Obviously I don't want to copy-paste into a new ControlTemplate and just make that change because I'll double the code base and if I make a common change to the template I'll need to change both.

I've thought of three solutions that seem like they may work, but I don't know enough about XAML (and especially refactoring XAML to know if these are possible)

  1. Extract the common XAML into a base ControlTemplate and 'override' the checkbox visibility in two new ControlTemplates (I place the override in quotations because I'm using C# speak - I've no idea if that makes sense in XAML!)

  2. Gain access to the checkbox (via x:Name or x:Key maybe) from outside of the ControlTemplate definition, then setting the Visibility would be trivial.

  3. Specify some kind of binding on the Visibilty in the ControlTemplate, something like:

    <Checkbox Visibility={Binding someNewPropertyOfTheTemplate}/> (Is this what TemplateBinding is used for?)

Are any of these ideas valid? And if so, which is the most appropriate? (If not - what is the correct way?)

I'm using VS2010 with .Net 4.0.

Upvotes: 5

Views: 852

Answers (1)

Vladimir Perevalov
Vladimir Perevalov

Reputation: 4159

I would go for #3. But your code is not quite correct. If you want to bind to properties of the actual control, on which template is being applied, you should use TemplateBinding. Suppose you have a custom control with a property ShowCheckboxes. Then in your template you should use

<Checkbox Visibility={TemplateBinding ShowCheckboxes, 
                      Converter={StaticResource BooleanToVisibilityConverter}}/>

Note, you may have to reference or create appropriate converter. On the other side, if you use MVVM, you may define your control property on the viewmodel class. Then you should use {Binding}.

Also, there is another way to control which templates are applied. You may extract the template for your subcontrol out of the big template. And copy it, so you have two templates, that differ in the way you need. Then, in the main template you can set TemplateSelector for your subcontrol to the custom class, that you will implement. Look at the http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector.aspx for more examples.

Upvotes: 3

Related Questions