Templates in extended Silverlight controls - silverlight

i am looking to extend a third party control, it is a ComboBox (so it isn't the standard Silverlight one, but that shouldn't matter for this question). To do this, i add a new template control to my controls project, then i change the new control to inherit from ComboBox instead of Control. A style has been created for me in the generic.xaml file, so i delete the default border stuff that was inserted, and then add a property setter for the PopupTemplate.
My problem is that when doing it this way, the combobox doesn't (visibly) render in the silverlight application anymore. However, in the constructor of my extension if i comment out the line
this.DefaultStyleKey = typeof(MyComboBox);
and put the PopupTemplate xaml bit in the main silverlight page, it renders correctly. I want the popup template to be declared within the control library, but does this mean that i also have to define the regular Template property? Am i wrong in thinking that anything i don't explicitly specify should just be inherited from the base control?

A control can only have one default style. You need to copy the entire default style of the base control into the Generic.Xaml for you new MyComboBox then adjust it accordingly.

Related

Custom Control Appearance

I created my own user controls that inherit from the standard .net controls (for example MyTextBox : TextBox). MyTextBox has within it some custom logic, and also sets some style properties (eg colour). I build the project that contains these controls, and they get added to my toolbox. I then drag them onto the windows form designer. The problem is that when I drag them, the windows form designer automatically includes the style definition for the control that i dragged. For example
this.myTextBox1.BackColor = System.Drawing.Color.Gray;
Now, if later on during development I decide to change the colour for all instance of MyTextBox in the solution from Gray to White, I cannot simply go to the MyTextBox control code, change it there and rebuild. The change will not be applied to existing text boxes, since this property will be overridden in the forms designer! What is the best approach to handle such cases?
you can control the designer code generation with an attribute ... http://msdn.microsoft.com/en-us/library/system.componentmodel.designerserializationvisibilityattribute.aspx

Silverlight: Style for Custom Control in Same Project

I have a Silverlight application with a custom control MyDataGrid which is a DataGrid with some extra features.
This is part of the project in which it is used. It also requires a custom style. I can add the style to my style resource dictionary and set TargetType="sdk:DataGrid" which works.
However, my style relies on a property MyProperty specific to MyDataGrid, so a warning appears in the editor. More importantly, the styles cannot be previewed in the designer.
They DO work when the code is run, however.
My question is: Is there a way to pull in local controls to a resource dictionary, rather than creating a separate project, compiling it to a .dll, and pulling in that assembly?
Thanks!
It sounds like you made a custom control, but you haven't defined a default style for it. Try the following:
In your project, add a folder at the root level called Themes.
In the Themes folder, add a ResourceDictionary named generic.xaml.
Add all of your MyDataGrid styles to generic.xaml.
Make sure one of the styles is an implicit style (using BasedOn is a great solution here).
In the default constructor for MyDataGrid, add the line DefaultStyleKey = typeof(MyDataGrid);
If you want to access part of the style (which is defined in XAML) from code, you should name that XAML item as "PART_something". The design tools understand the PART_* syntax plus that's an indication to library consumers that if you retemplate the control, you must define the required pieces prefixed with PART_.
Here are the basics on how to define a custom control.

How is a a ControlTemplate instantiated in XAML?

In code a ControlTemplate contains a hierarchy of FrameworkElementFactory that can be used to construct the framework elements themselves. But, in XAML, a ControlTemplate's content appears as the elements themselves.
Does the XAML parser convert from one object form to the other, is a ValueConverter used, or does it actually create the factories as it parses the ControlTemplate content?
It is actually done differently, if it's defined in XAML versus in code. To verify, you can create a simple project in WPF with a single Window and add a custom Control that has a ControlTemplate defined in XAML by it's default Style. Then add the control to your window and add a Button, whose Click handler includes a breakpoint.
When the breakpoint is hit, we can inspect the custom control and it's ControlTemplate. The VisualTree property (which is FrameworkElementFactory) is null.
Using Reflector, we can see the relevant code in the StyleHelper.ApplyTemplateContent method. The first if-statement in that method, applies a FrameworkElementFactory (which is passed in from the VisualTreeProperty). The second if-statement loads the ControlTemplate from XAML, which ultimately executes FrameworkTEmplate.LoadOptimizedTemplateContent.

How to style a custom Silverlight 4 UserControl?

I have a custom UserControl that I created as a navigation menu that parses an xml file and populates itself with hyperlink buttons. So basically my control is an empty stackpanel, and when it's loaded it adds hyperlinkbuttons as children to the stack panel.
In my application I just add a <myLibrary:NavigationMenu links="somexml.xml" />
The problem is that I want to be able to style the hyperlinkbuttons and the stack panel differently for every application. What is the best way to do this.
In the code behind for the control, create a DependencyProperty of type Style for both HyperlinkStyle and StackPanelStyle. Then when you create the items apply the correct styles too them.
Take a look at MSDN
The article is a good starting point for writing stylable controls.

Overriding method of an element within a XAML UserControl?

I have a Silverlight user control that has no template and does not need one as it is simply a path with a RectangleGeometry that is resized by code. Now our designed has added a template to the tooltip of the path and I want to be able to provide a method for users of the control to change the layout of a portion of this template. If the template was part of an overall one for the control I could simply override the control's OnApplyTemplate method and grab a reference to the section I want to modify. But as the control has no template the overridden method in the control's code-behind is never called.
Is there some way I can override the OnApplyTemplate method for the templated element in the control's code behind?
What is the base-class. You can't override OnApplyTemplate if the underlying class doesn't support templates. I think you'd be best to just change the tooltip style when the value is set (as its unlikely to show up anyway).
Any reason you can't just do GetTemplateChild as the path changes? That should be late enough in the lifetime.

Resources