Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Content alignment and positioning in templated wpf control

I'm a professional Windows application developer in VB.NET and C# with Windows Forms, and now very excited to step into WPF development. Here my first issue I couldn't solve by searching:

I wrote the following template to completely change the appearance of my buttons:

    <ControlTemplate TargetType="{x:Type Button}" x:Key="ImageButtonTemplate">
        <Grid>
            <Image Name="img" Source="/PSPlayer;component/Images/Buttons/ButtonNormal_normal.png"/>
            <ContentPresenter Stylus.IsTapFeedbackEnabled="False" Stylus.IsTouchFeedbackEnabled="False" Stylus.IsPressAndHoldEnabled="False" Stylus.IsFlicksEnabled="False" Width="98" Height="61"/>
        </Grid>

        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter TargetName="img" Property="Source" Value="/PSPlayer;component/Images/Buttons/ButtonNormal_MouseOver.png"/>
            </Trigger>
            <Trigger Property="IsPressed" Value="True">
                <Setter TargetName="img" Property="Source" Value="/PSPlayer;component/Images/Buttons/ButtonNormal_MouseDown.png"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

and here a button definition:

        <Button Content="SomeText" Height="61" Margin="0,0,0,7" Name="button7" Width="98" Click="button7_Click" Template="{StaticResource ImageButtonTemplate}"/>

The problem is, that the Text "SomeText" appears in the top left of the button and I cannot change that location. The buttons' properties HorizontalContentAlignment and VerticalContentAlignment don't show an effect (I'm wondering why).

Additionally I would like to position the text to a certain location sometimes, like x=70 when the backgound image has a symbol in it that locates on the left side until x=60.

I made a walkaround with a label embedded inside the button that I could position but think there must be a cleaner solution.

Hope I made myself clear. WPF rulez by the way - as well as this site, most of my problems I solved with postings from here (coming from google) :)

Thanks in advance,

Julian

like image 657
Julian Avatar asked Feb 20 '23 21:02

Julian


1 Answers

A few things are happening here. Your first problem is that you set an absolute size for your ContentPresenter (in general, in WPF, you avoid absolute sizes and absolute positions for controls, but it's a hard habit to break when you are coming from WinForms). If you remove that it will can be aligned properly by setting the VerticalAlignment and HorizontalAlignment of the ContentPresenter itself. The reason why setting the VerticalAlignment and the HorizontalAlignment on the button itself doesn't work is because you are not using those properties anywhere in your template. Ideally, you'd do something like this:

<ContentPresenter VerticalAlignment="{TemplateBinding VerticalAlignment}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"/>

And now you can set the alignment on the button that uses this template. Of course, if you always want this template to be centered, you can just hardcode it rather than using the TemplateBinding.

In general, the thing to remember when replacing templates is that any property of the control that you are not explicitly binding in your template is going to be ignored by WPF when it renders your control. If you don't tell it what to do with those properties it isn't going to guess. A rare exception is the content property in your example which you can get away with not explicitly binding since WPF will assume you intended to put it in the ContentPresenter! But all the other button properties are going to be ignored. For example, if you try changing the Background property of your templated button, it will be ignored because WPF doesn't know where to put that background. Should it be the whole control? Should it be your grid? Just your ContentPresenter? You have to tell it.

like image 155
Matt Burland Avatar answered Apr 09 '23 03:04

Matt Burland