I have a reasonably 开发者_JS百科simple button ControlTemplate to style a button. I have been asked to align a portion of the text for the button to the right of the button. Therefore Some text will be aligned left and some right. A pointer to an approach for this would be appreciated. This is what I have so far:
<ControlTemplate x:Key="ListItemNameTemplate" TargetType="Button">
<Grid Height="40">
<Border Width="200"
x:Name="BgEnabled"
HorizontalAlignment="Center"
Margin="1,1,1,1"
Background="YellowGreen">
<StackPanel Orientation="Vertical">
<TextBlock Width="150"
x:Name="textBlock"
Text="{TemplateBinding Content}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="White"
FontSize="24"
FontWeight="Bold"/>
<TextBlock Width="50"
x:Name="textBlock1"
Text="{TemplateBinding Content}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Foreground="White"
FontSize="24"
FontWeight="Bold"/>
</StackPanel>
</Border>
</Grid>
</ControlTemplate>
however: a. The second textblock does not display. b. I need to specify the content for the second textblock differently than "Content".
You can subclass Button
to introduce a new dependency property for the right-aligned text, you will be stuck with the Content
property though (you could create two new properties and throw an exception if Content
is set though).
To get the layout right you should either use a Dockpanel
(dock left and right, LastChildFill
set to false
) or a Grid
(with three columns, middle takes rest, left & right is auto-sized).
Like this:
<Window.Resources>
<ControlTemplate TargetType="{x:Type Button}"
x:Key="MyButtonTemplate">
<Border>
<DockPanel LastChildFill="True">
<TextBlock Text="{TemplateBinding Content}"
DockPanel.Dock="Top"/>
<TextBlock Text="{TemplateBinding Content}"
TextAlignment="Right" />
</DockPanel>
</Border>
</ControlTemplate>
</Window.Resources>
<Button Template="{StaticResource MyButtonTemplate}">
Hello World
</Button>
Looks like:
If you want the second text different then just create a second property. I would create an attached dependency property so you can still use TextBox without having to subclass it and screw up all the UI elements in your project. Use the snippet "propa" to get started in Visual Studio. It's easy. See here: http://msdn.microsoft.com/en-us/library/ms749011.aspx
Like this:
public class MyButtonThing
{
public static string GetText2(DependencyObject obj)
{
return (string)obj.GetValue(Text2Property);
}
public static void SetText2(DependencyObject obj, string value)
{
obj.SetValue(Text2Property, value);
}
public static readonly DependencyProperty Text2Property =
DependencyProperty.RegisterAttached("Text2",
typeof(string), typeof(System.Windows.Controls.Button));
}
And this:
<Window.Resources>
<ControlTemplate TargetType="{x:Type Button}"
x:Key="MyButtonTemplate">
<Border>
<DockPanel LastChildFill="True">
<TextBlock Text="{TemplateBinding Content}"
DockPanel.Dock="Top"/>
<TextBlock TextAlignment="Right" Text="{Binding
RelativeSource={RelativeSource AncestorType=Button},
Path=(local:MyButtonThing.Text2)} " />
</DockPanel>
</Border>
</ControlTemplate>
</Window.Resources>
<Button Template="{StaticResource MyButtonTemplate}"
local:MyButtonThing.Text2="Where's Waldo">
Hello World
</Button>
The attached property route was certainly the way to go to solve this issue. A new subject for me and the examples did not work for me. The control template was not able to recognize the new property. The change that worked was the way to modify how the attached property is defined.
Thanks to this article for the pointer: http://www.deepcode.co.uk/2008/08/exposing-new-properties-for-control_15.html
public class MyButtonThing : DependencyObject
{
public static readonly DependencyProperty SubTextProperty =
DependencyProperty.RegisterAttached("SubText",
typeof(String), typeof(MyButtonThing),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.AffectsMeasure |
FrameworkPropertyMetadataOptions.AffectsArrange));
public static void SetSubText(UIElement element, object o)
{
element.SetValue(SubTextProperty, o);
}
public static string GetSubText(UIElement element)
{
return (string)element.GetValue(SubTextProperty);
}
}
精彩评论