How do I replace a ControlTemplate part at runtime, in Silverlight 3? - silverlight

I'm writing a custom control which uses a template defined in the resources section of my XAML and I'd like to replace one or more template parts in an instance of my control at runtime.
For example, if I have a part named "ActivePart" in the control's template, how do I replace the ActivePart's FrameworkElement in an instance of the control with a new FrameworkElement?
I realise the Control.Template property is writeable, but I'd prefer to find a way to replace a specific part of that template rather than create a whole new one, although a solution that edits the existing template by replacing the appropriate named part would be acceptable.
I'm using C# and need to do this at runtime using any FrameworkElement, so I'm not looking for XAML-based solutions or suggestions, thanks!
P.S. I'm aware that GetTemplateChild() returns the FrameworkElement for a named template part in a control instance, but I don't see how that helps me to replace that part with a new FrameworkElement.

I guess I was missing the obvious!
After OnApplyTemplate is called on your derived Control, VisualTreeHelper.GetChild (this, 0) will return the root object of the instantiated template's visual tree, from which you can use the Children collection (if your Control's template is Panel-derived, e.g. Canvas, Grid, etc.) to add/remove/modify any of the child template parts to your heart's content.
Before OnApplyTemplate is called, no visual tree exists for the Control, and VisualTreeHelper.GetChildrenCount returns 0.

Related

How to get the Namescope of a control in UWP/Windows 8.1

WPF has a method called NameScope.GetNameScope(control). How can you get the same thing in UWP/Windows 8.1? The runtime must be doing it internally somehow or else ElementName bindings wouldn't work
XAML namescopes do exist in UWP, but currently there's no public API similar to WPF's GetNameScope(control).
Depending on what you're trying to achieve, you will most likely have to fall back on using FindName or GetTemplateChild methods or ultimatly the VisualTreeHelper.
Because of the separate XAML namescopes, finding named elements within
a template from the scope of the page where the template is applied
requires a different technique. Rather than calling FindName on some
object in the object tree, you first obtain the object that has the
template applied, and then call GetTemplateChild.

Accessing a 3rd-party ContentTemplate-internal control

I'm using a 3rd party control (in this case, Telerik's RadChart control), which has a complex inner ControlTemplate that encompasses several elements of the chart. Unfortunately, not all parts are exposed explicitly for me to style, and I find myself wanting to set a property on a particular sub-element inside the ControlTemplate, either via XAML or via code. After struggling with the XAML for a while, I settled for a code-centric approach, but I'm still stuck.
Using Snoop, I can see that the top-most ChartArea control (which I can access) renders an AxisX2D object named PART_AxisX, which in turn has a template which contains the PART_AxisLabels object, which is the one I need to style. (Incidentally, the property I want to set is AlternationCount, but I couldn't find a less hacky way of getting to it).
I tried to use the ControlTemplate.FindName method (as shown here) to get the AxisX2D object, and then again on that object to get the AxisLabels object, but FindName always returns null:
var chartArea = myChart.DefaultView.ChartArea;
var visualAxisX = chartArea.Template.FindName("PART_AxisX", chartArea) as AxisX2D;
even though Snoop confirms that chartArea is, in fact, the AxisX2D's TemplatedParent. I checked in the debugger and I could find PART_AxisX in chartArea's internal Template property.
So my questions are:
1) What am I doing wrong here?
2) Is there a better way to approach this that isn't as roundabout as this?
The solution is to wait till after the Loaded event has occurred on the Control.
When this event has occurred you know that the Template has been applied and the visual tree has been built for the control, and so you can then access the elements using FindName.
http://blogs.msdn.com/b/mikehillberg/archive/2006/09/19/loadedvsinitialized.aspx
Slightly related link given here for case when using a Content Template on a ContentControl.
Why would 'this.ContentTemplate.FindName' throw an InvalidOperationException on its own template?

Extending a subelement within a ControlTemplate

I’m trying to extend an Expander’s header (the ToggleButton part) to allow for some more custom features. Being rather new to extending WPF controls using ControlTemplates, I have already accepted by now, that I will have to completely replace the Expander’s template by my own (without being able to reuse originally defined components, or even styles, which makes this quite a bit annoying in my opinion – but that’s not what the question is about).
However, I wanted to introduce some properties which change the way the component looks and works. So I created a new subtype of Expander which simply defines the new dependency properties I want to use. But I noticed that, given that I want to use those properties within the template for the ToggleButton, which is nested inside of the one for the Expander, I cannot use those properties like that. So I had to subtype ToggleButton too, define the dependency properties for that type as well, and make the Expander’s template pass the values through to the ToggleButton template.
So I ended up with two new types in the namespace (nesting the new ToggleButton type inside of the Expander subtype didn’t work?), a complete copy of the Expander’s template with only a single line changed (where the ToggleButton was inserted, passing through the new properties), and then the actual desired changes for the ToggleButton template.
And here comes the question: Is there any way to make this less complicated? To reduce the amount of work that needs to be done just for extending a subcomponent of another’s template? Or just a way to use the parent’s (Expander) properties inside of the ToggleButton template without having to subtype that one as well?
I ended up using what jberger suggested in the comments:
Using the following binding expression I did not need to duplicate the DependencyProperties into another component for the ToggleButton, but could just access the Expander’s properties inside the nested template:
{Binding CustomProperty, RelativeSource={RelativeSource
FindAncestor, AncestorType=local:CustomExpander}}
Sadly, but as expected, one apparently cannot reuse template parts from the default. However in this case I could leave out parts from the original template that I didn’t need in my copy. For example the different styles for non-default expanding (i.e. other than Top), as my expander is specialized to that layout.
This however rendered the ExpandDirection property useless, but I personally can accept that. It might lead to a follow-up question though; if one should rather build the component from scratch (based on Expander’s base, instead of Expander itself).

Modify XAML string dynamically

I want to add/remove some part of XAML dynamically i.e. from code behind file in C#.how to Add any specific XAML string on specified location (means under some tag) from .cs file. Please help.
XAML is xml you can use XmlReader and XmlWriter or any other of the XML serialization mechanismn of .NET to write/read XML (XMlDocument is probably the best approach here to modify existing xml). ALso there are the XamlReader and XamlWriter class that allow ou to (de)serialize any object graph from/to XAML automatically. If you can use .NET 4.0, you have even more fine grained possibilities to athor XAML because it has a new XAML stack. Use this as a starting point.
What is it that modifying the XAML will do for you?
If you just want to change the appearance of your WPF application (perhaps by adding some more content at certain locations), it will most likely be easier to do this by referencing the objects in question. So, if you need to add some text to a button, name the button with x:Name="myButton" and in code set: myButton.Content = "Click Me"
XAML is really a technology for constructing object hierarchies. Pretty much every element in the XAML corresponds to a .NET CLR class. When loaded, these classes are instantiated nd populated according to the attributes used in the XAML. Once loaded, the XAML has finished it's job and is essentially unloaded/unavailable.
You might need to do something beyond this, but from your brief question it doesn't seem like it. I would just work on the object model and leave the XAML be.

WPF: Switch Template based on UserControl Data

Trying to implement what I thought was a simple concept. I have a user control (view) bound to a view model which provides a list of data. I have added toggle buttons to the usercontrol and would like to allow the user to use these toggle buttons to switch out which template is used to show the data. All of the templates used for the data work, and they are very different from one another so it's not just simple changes to a single template. I'd like to get this as much in XAML as possible.
Here's what I have now:
Where the data appears I have <UserControl Template="{StaticResource ListSwitchingControlTemplate}" />
In that control template I have all "sub templates" - really it's just all 3 representations with their visibility set to Collapsed. Then I use a data trigger on that control template to show the currently selected view. This works, but I noticed that all 3 representations get bound - they each act like they are active (and they are I guess).
I'd rather be able to truly switch the template at run time. I tried converting the containing user control to use a ContentTemplate for itself, but that just messes up all of the binding I have elsewhere. If only UserControls could use DataTriggers I'd be ok.
Any suggestions on how to cleanly go about getting this behavior. I have an idea that I'm just missing something simple.
Thanks,
Dave
you could do it via code?
http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-a-datatemplateselector ???
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/4fd42590-8375-46d0-b7bc-6c217df0f0ba/
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/dbbbb5d6-ab03-49a0-9e42-686fd41e0714
One way to do this would be to use a DataTemplateSelector.
Basically, you create a class that inherits from DataTemplateSelector and override its SelectTemplate virtual function. The return value from the function is the DataTemplate you want to use and in that function you have access to the object and its properties, which you can use to decide which template to select.
There is an example on MSDN here:
http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector.aspx

Resources