开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜