Styling a control template in Silverlight 5 - silverlight

I'm looking at using the Silverlight Menu Control from Codeplex. It's functionally very good but I'd like to restyle the appearance. Is it possible to do this without just making a new copy of the template and changing a few properties? Here's an example from the generic "theme" that comes with the control:
<Style TargetType="GenericControl:MenuBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GenericControl:MenuBar">
<Canvas x:Name="LayoutRootMB">
<StackPanel Height="25"
x:Name="baseRectMB"
Canvas.Left="0"
Canvas.Top="0"
HorizontalAlignment="Left"
Orientation="Horizontal" />
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I'd like to change, say, HorizontalAlignment to Stretch (for the sake of argument -- never mind if it'll actually accomplish anything useful). Is there any way to tell XAML (in XAML, not in C#) that I want to do something to baseRectMB?
baseRectMB is named in a TemplatePartAttribute on class MenuBar.
I assume I can simply copy the existing template and alter it, though I haven't gotten that working yet either.

Related

Ensuring AdornmentDecorator within a ContentPresenter, but without a ControlTemplate

I've searched around quite a bit and can't seem to crack this nut.
I've got an app with a main view that changes dynamically, and to do this I use content presenter with a binding to a control:
<ScrollViewer Grid.Column="2" x:Name="StepScrollViewer">
<StackPanel Margin="20,20,20,500">
<ContentPresenter Content="{Binding MainControl}"/>
</StackPanel>
</ScrollViewer>
Then I change the MainControl at runtime in my view model. The problem is that the controls getting bound don't reliably display their error templates... I suspect it is for the reasons discussed here:
Validation ErrorTemplate not showing on data errors
But the fix for this problem doesn't seem to work for me because I'm not using a control template around my content presenter. When I wrap an AdornmentDecorator tag around my content presenter, it doesn't seem to fix the problem. It DOES work if I put an AdornmentDecorator inside each control I load into the contentpresenter (as the root element), but I'd like to avoid this repetition if possible.
Any insights?
UPDATE
I tried this approach suggested by Dennis, but to no avail. The control binds okay, but it works no better than the current approach (also shown commented below). Note: I tried it both with the AdornerDecorator as a singleton element the way Dennis has it, and surrounding the ContentPresenter, as shown below. Neither show any difference - the adorners around my controls all disappear when the MainControl binding is changed.
<UserControl.Resources>
<Style x:Key="MainContentControl" TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<Grid>
<AdornerDecorator>
<ContentPresenter Content="{Binding MainControl}"/>
</AdornerDecorator>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
.....
<ScrollViewer Grid.Column="2" x:Name="StepScrollViewer">
<StackPanel Margin="20,20,20,500" >
<ContentControl Style="{StaticResource MainContentControl}"/>
</StackPanel>
</ScrollViewer>
<!-- THE BELOW WORKS IF I SURROUND EACH BOUND CONTROL WITH adornerdecorator -->
<ScrollViewer Grid.Column="2" x:Name="StepScrollViewer">
<StackPanel Margin="20,20,20,500">
<ContentPresenter Content="{Binding MainControl}"/>
</StackPanel>
</ScrollViewer>
-->
Instead of using a ContentPresenter directly, I would instead use a ContentControl. A ContentControl is the base class for controls that contain other elements and have a Content property, e.g. Button.
Then you can override the template to have an AdornerDecorator next to the ContentControl. This is different to what you previously tried as now the ContentPresenter is part of the same visual tree as the Adorner.
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<AdornerDecorator>
<ContentPresenter/>
</AdornerDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Edit: Forgot that the AdornerDecorator needs to wrap the container, not just sit side-by-side.

Binding ContentPresenter.Content to TemplatedParent (WPF/Silverlight)

Basically, I would like to overlay, for example: TextBlock over Button, by using ControlTemplate (applied to this Button), but I don't want to get rid of default template of it.
Example:
<Grid Grid.Row="1" Grid.ColumnSpan="2">
<Grid.Resources>
<Style x:Key="myStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<ContentPresenter />
<TextBlock Text="textBlock"
Margin="10" Foreground="Red"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Button Style="{StaticResource myStyle}" Content="button1"></Button>
</Grid>
and it gives Button stripped of it's default template:
Rather, I would like to receive something like this:
Is it possible by using ControlTemplate? I was trying to bind TemplatedParent to ContentPresenter.Content like here:
<ContentPresenter Content="{Binding
RelativeSource={RelativeSource Mode=TemplatedParent},
Path=.,
Mode=TwoWay}"/>
or other combinations, but I couldn't make it work.
Edit:
Because I would like to be able to apply this TextBlock not only to a button (it was just an example) but to any Control, I don't want do it by copying default style (to the resources or somewhere), for every Control.
Also, I would prefer not to create UserControl, because I would like to keep xaml clean as much as possible (I mean with system Controls) - and just to turn on/off the overlaying TextBlock by using a ControlTemplate.
You could add the default style on the button and modify it to add your TextBlock. The second option, my preference, is to create a new UserControl that will contain the Button and the TextBlock with IsHitTestVisible=False. You can then add dependency properties to be able to bind to the button and the text block.

Avalon Dock v2 Layout Issue

I am currently working with avalon dock v2, in the template of my document sources, i'm also putting in a docking manager.
Yes for each of my document, I want anchorable panes inside it. But when I try to do that, it doesn't work, it just shows the toString of the docking manager for each of the document, is there a way to fix that.
Also, how do i default dock my anchorable?
Thanks and Regards,
Kev84
In creating a template for the AvalonDock's LayoutDocument (via the LayoutDocumentControl) I also came across a similar issue. The solution was to set the ContentSource of the ContentPresenter to point to the Model property of my control. The code below illustrates it:
<!--The LayoutDocument is templated via the LayoutDocumentControl-->
<Style TargetType="{x:Type ad:LayoutDocumentControl}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ad:LayoutDocumentControl}">
<ScrollViewer
Background="AliceBlue"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" SnapsToDevicePixels="True">
<!--Make sure that the ContentSource points the Model Property of the Control-->
<ContentPresenter
Content="{Binding Path=Content, UpdateSourceTrigger=PropertyChanged}"
ContentSource="{Binding Path=Model, UpdateSourceTrigger=PropertyChanged}"
/>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
A similar approach should apply to your case. This is just a temptative answer (since I am also new to AvalonDock 2.0), but it may be worth trying.
Live long and prosper!

ItemContainerStyle in Custom Control Derived From ListBox

Please bear with me Silverlight Designer Gurus, this is compicated (to me).
I'm creating a custom control which derives form the Silverlight 3.0 ListBox. In an effort not to show tons of code (initially), let me describe the setup.
I have a class library containing a class for my control logic. Then I have a Themes/generic.xaml that holds the styling details. In generic.xaml, I have a style that defines the default layout and look for the ListBox where I'm setting a values for the Template, ItemsPanel and ItemTemplate.
In my test app, I add my control on to MainPage.xaml and run it and it works great. I dynamically bind data to my control and that works fine.
Now I want to set the ItemContainerStyle for my derived control. If I create a style in the MainPage.xaml file and set the ItemContainerStyle property to that control as in:
<dti:myControl x:Name="MyControl1" ItemContainerStyle="{StaticResource MyListBoxItem}"
Height="500"
Width="200"
Margin="10"
Background="AliceBlue"
/>
It works as expected.
However, I'd like to do this in the class library or, more specifically, in generic.xaml. I tried to this Setter to my current Style:
<Setter Property="ItemContainerStyle">
<Setter.Value>
<ControlTemplate>
<Grid Background="Red" Margin="3">
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="Stretch" Margin="3"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
And it fails miserably with:
"System.ArgumentException: 'System.Windows.Controls.ControlTemplate' is not a valid value for property 'ItemContainerStyle'."
Note: This is not my actual style I'd like to use for ItemContainerStyle. I'm actually looking to plug in some VSM here for the various selected/unselected states of the a ListBoxItem (for a dynamically bound control).
So, to the question is how do I apply the ItemContainterStyle to my custom control when it's defined using generic.xaml? I do not want that property set when I actually use the control later on.
Thanks,
Beaudetious
You missed to put Style tag inside your Setter.Value. ItemContainerstyle explects a Style to ListBoxItem(Unless you subclassed ListBoxItem to your own derived version.)
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType=”{x:Type ListBoxItem}“ >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="Red" Margin="3">
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="Stretch" Margin="3"/>
</Grid>
</ControlTemplate>
<Setter.Value>
</Style>
</Setter.Value>

WPF ControlTemplate with foreach?

I currently try to create classes for a paint-like WPF application. I have to base classes LineMovement (line from StartPoint to EndPoint) and PathMovement (line going through all points specified in a property Points of type PointCollection). These classes inherit from Control and get their looks through a ControlTemplate.
Now I want to add (what I call) PointMovers to the ControlTemplate. These should be little visual elements residing on each of the points in either of the Movement classes. They should become a kind of grip mechanism to drag the underlying point around.
The problem is of course that I don't know a way to create a variable number of elements in a ControlTemplate. It would be cool if I could do something like this:
<Style x:Key="{x:Type mov:PathMovement}" TargetType="{x:Type mov:PathMovement}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type mov:PathMovement}">
<Grid>
<Polyline Points="{TemplateBinding Points}" />
<!-- interesting part start -->
<foreach loopvariable="Point" in="{TemplateBinding Points}">
<PointMover Point="Point" />
</foreach>
<!-- interesting part end -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Is this possible? Do you have another approach in mind that could work?
Thanks in advance!
Use an ItemsControl in conjunction with an ItemTemplate:
<ItemsControl ItemsSource="{Binding Points}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- rendered for each point -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
By the sounds of your use case, you may also want to read up on AdornerLayers.

Resources