How to apply default style to control in custom control - silverlight

I have a custom control which is dynamically adding a number of checkboxes. I can't figure out how to apply a default style to them from code in the custom control (from the generic.xaml file)

I am having a shot in the dark here, but do you have a default "theme" file that you want to apply to dynamically added UIelements in some custom UserControl?
if so,
Try something like:
public Page()
{
InitializeComponent();
Uri uri = new Uri(#"QuoteInterface;component/Theme/WhistlerBlue.xaml", UriKind.Relative);
ImplicitStyleManager.SetResourceDictionaryUri(LayoutRoot, uri);
ImplicitStyleManager.SetApplyMode(LayoutRoot, ImplicitStylesApplyMode.Auto);
ImplicitStyleManager.Apply(LayoutRoot);
}
That seems to work for me, even when I add dynamically generated user controls

Related

What's the best way to give a dependency property a default value from a resource dictionary

I'd like to create a WPF user control (or custom control). The user of this control should be able to re-template a certain part of this control. For that I created a dependency property called "SubTemplate".
Public Shared ReadOnly SubTemplateProperty As DependencyProperty =
DependencyProperty.Register("SubTemplate", GetType(DataTemplate), GetType(MyControl), New FrameworkPropertyMetadata(Nothing))
Of course there should be a default template that's used, when the user doesn't give it's own template. But how do I give this default value to the dependency property?
I'd like to define this default template in XAML (probably in a resource dictionary, maybe in Themes\Generic.xaml?)
Is there a way to exchange the Nothing default value with a template from a resource dictionary?
Or do I have to set the default value in the constructor of my control (still don't know how to access a named template from a resource dictionary in code behind, FindResource doesn't seem to work or I'm using it wrong).
Or do I have to set the TargetNullValue of the binding I use to add the template to the re-templated part of the control?
Right now I just set the "SubTemplate" property in the default style of my control, but if the user restyles the whole control and forgets to give a "SubTemplate", then it would be Nothing.
Is there a way to exchange the Nothing default value with a template from a resource dictionary?
If you add the default DataTemplate to your App.xaml file, this should work:
Public Shared ReadOnly SubTemplateProperty As DependencyProperty =
DependencyProperty.Register("SubTemplate", GetType(DataTemplate), GetType(MyControl), New FrameworkPropertyMetadata(Application.Current.Resources("KeyOfTemplate")))
If you want more control over things you could write some code that looks up the template, for example in the OnApplyTemplate method of the control. You may want to get it from somewhere else, check that it actually exists, etc.

How do I make user controls for both ListView and ListViewItem work with each other?

I have all the styling, triggers, etc. down for ListView and ListViewItem, and I want to turn them into user controls. How do I make sure that these two "match up" with each other, so that MyListView accepts MyListViewItems as content? Also, considering that I must end the ListView tag by the end of the user control XAML file, I am not sure how I would add items to it.
If you want them to be reusable with different data sets, especially through binding, you should stay away from UserControls and just make custom controls derived from the original types. In that case you create a standalone MyListView.cs and MyListViewItem.cs and all of the XAML for the controls goes into default Styles (usually also containing a ControlTemplate) in Themes/Generic.xaml. You can see an example of this setup by just adding a WPF Custom Control to your WPF project from Add New Item.
Once you've created the .cs files for your custom controls you just need to override a few methods from the base ItemsControl to use MyListViewItem as the item container control. The ListView would end up like this:
public class MyListView : ListView
{
static MyListView()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyListView), new FrameworkPropertyMetadata(typeof(MyListView)));
}
protected override DependencyObject GetContainerForItemOverride()
{
return new MyListViewItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is MyListViewItem;
}
}
You can now use your custom MyListView exactly as you would a normal ListView, including binding to ItemsSource.
Inheritance should take care of that for you. In other words, if you have two user controls, the first one with a basic element of ListView (not UserControl) and the other of ListViewItem (again, not UserControl), and you make sure they extend ListView and ListViewItem respectively in the .cs code, the following should work equally:
ListView lv = new ListView();
lv.Items.Add(new ListViewItem());
or
MyListView mlv = new MyListView();
mlv.Items.Add(new myListViewItem()); //If your myListView extends ListView, and myListViewItem extends ListViewItem in your user control files, of course
In case you are looking for a XAML solution, you should import your namespace at the top
xmlns:myControls="WhateverYourNamespaceAndAssemblyAre"
and on you page/window/whatever
<myControls:myListView>
<myControls:myListViewItem/>
<myControls:myListViewItem/>
</myControls:myListView>

Create Silverlight custom control with code only (no xaml)

I would like to create a Silverlight custom control using C# only, without any xaml.
Here is my work so far (stripped down to the bare minimum for the question):
I tried to inherit User control as follows:
public class myControl: UserControl
{
// class code
}
And adding it to the LayoutRoot:
myControl control = new myControl();
LayoutRoot.Children.Add(control);
The control is added, but its invisible!!
How can i make it visible ? Is there something i missed ?
edit: The only visual element in my contorl is a grid with an image background
Your Usercontrol will be empty and have no visual effect until you give it a child control via it's Content property.
Well unless you put a template in place or add elements in code, UserControl is empty.
Maybe you could try inheriting from an existing control which has a template, like Button, etc and change that in code?

How to replace a ResourceDictionary of a 3rd Party UserControl (in this case PivotViewer)

The current version of the Microsoft Live Labs PivotViewer control for SilverLight 4 has no way to style the elements of the control. Looking at the control in Reflector, I can see much of the style info is set in a ResourceDictionary in the assembly (assets/defaultcolors.xaml). What I would like to do is create my own copy of this file, then replace it at runtime on the PivotViewer control.
By subclassing the PivotViewer control and overriding OnApplyTemplate I can grab the child elements and set properties such as Background. I have not had any success Clear()'ng the MergedDictionaries and adding in my own:
public override void OnApplyTemplate() {
base.OnApplyTemplate();
/* can change things this way */
CollectionViewerView cvv = ((CollectionViewerView)((Grid)this.GetTemplateChild("PART_Container")).Children[0]);
((Grid)cvv.Content).Background = new SolidColorBrush(Colors.Black);
/* can't change things this way */
CustomDictionary gd = new CustomDictionary();
cvv.Resources.MergedDictionaries.Clear();
cvv.Resources.MergedDictionaries.Add(gd);
}
I'm afraid this isn't going to work in Silverlight because it uses only Static Resources. ( Styles Don't Update )
Changing a resource dictionary only works before InitializeComponent() is called, which is called in the constructor of the PivotViewer.
I've been trying to style the PivotViewer Control too. I hope there is another way, besides searching through the Visual Tree and changing properties.

How can I determine the type of the items that get added to a TabControl?

I've created a CloseableTabItem control that derives from TabItem.
Now I'd like to specify that a given TabControl should add new items using CloseableTabItem instead of TabItem.
Is this possible? How?
public class CloseableItemsTabControl : TabControl
{
protected override DependencyObject GetContainerForItemOverride()
{
return new CloseableTabItem();
}
}
You'll probably need to make your own ClosableTabControl that extends TabControl in order to override the base functionality.
However, you can also probably just add your tabs manually, feeding it your ClosableTabItems instead of regular TabItems. It would be safe to assume this is possible since most collection-based controls are able to be programatically populated this way.

Resources