Problem with button template in wpf..?
I am very new to wpf. I want to display an Image and a textblock in buttoncont开发者_StackOverflow中文版rol. Hence I created a template and binded image to source and textblock to name.
<ControlTemplate x:Key="ButtonControlTemplate1" TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="Storyboard1">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="border">
<EasingThicknessKeyFrame KeyTime="0:0:0.1" Value="1"/>
<EasingThicknessKeyFrame KeyTime="0:0:0.2" Value="0"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border x:Name="border" BorderBrush="Black" BorderThickness="0" Margin="0,0,-96,-21">
<Grid>
<Image HorizontalAlignment="Left" Margin="8,8,0,8" Width="34" Source="{Binding Source}"/>
<TextBlock Margin="46,8,8,8" TextWrapping="Wrap" Text="{Binding Name}" FontSize="16" Foreground="Black"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard1_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard x:Name="Storyboard1_BeginStoryboard" Storyboard="{StaticResource Storyboard1}"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Then I applied this template to the button. And I tried to add content via window loading event.
btnAddGropu.Content = new ToolButton() { Source = "Icons/add.png", Name = "Add Group" };
The ToolButton class
class ToolButton
{
public string Source { get; set; }
public string Name { get; set; }
}
When I executed the program with excitement and I didn't get button at all...!!! So whats the problem..? How I can use this template..?
Thank you In advance
Assuming that you have set your button with the control template as below...
<Button Template="{StaticResource ButtonControlTemplate1}"/>
The fix for you problem is to set DataContext
of the button and not its Content
.
btnAddGropu.DataContext
= new ToolButton() { Source = "Icons/add.png", Name = "Add Group" };
Although I must insist you change your way of displaying text and image via a ControlTemplate
that always expects a "specific" DataContext i.e. ToolButton
.
Control Templates and Data Binding, DataTemplates and User action effects are never to be mixed together.
:-)
Did you set this template to your button? You must set it, because you gave your ControlTemplate
a name, which makes it explicit. Without a name it would be implicit, thus it will be used automatically.
so
<Button Template="{StaticResource ButtonControlTemplate1}"/>
There are a couple more things in your example i want to point out. You set in your button the Content
to an instance of your class ToolButton
which is fine. This class is obviously not a WPF ui control, thus you must tell WPF what to do with it. Thats a DataTemplate
is for, you define a DataTemplate for your ToolButton class and now WPF knows how to display this one.
Unfortunately there is another problem in your Button Template
. Button is of type ContentControl
, thus allowing it to show any content. You already used the Content
property. But you are completely overriding the ControlTemplate, remember that a ControlTemplate defines how a control will look like, without its template it shows absolutely nothing.
Now looking at your template i miss a specialized control called ContentPresenter
this tells the template "When the button has a content, place it here" so the ContentPresenter is a place holder for the actual set Content. Now remember what i said about the DataTemplate
and you will see how these things work together.
Another tiny thing is, you use Bindings in your Template, but you never set the DataContext you just set the content, but the content is only valid inside the ContentPresenter, or better, your DataTemplate. There are a couple of "rules" around DataContext. Quick summarize: DataContext can be inherited and is automatically set in a DataTemplate
.
I hope this helps you abit. cheers.
I think that you need something like this:
<Button>
<StackPanel>
<Ellipse Height="40" Width="40" Fill="Blue"/>
<TextBlock TextAlignment="Center">Button</TextBlock>
</StackPanel>
</Button>
MSDN
you can replace the StackPanel with a Grid or DockPanel and embed any controls you want in this container.
I think in order to correctly handle the customization of a standard control you have to use ContentPresenter, which has a Style
of the button you want.
For example, look here: Example
精彩评论