Button control template with resizable circle?

This is where TemplateBinding comes in (TemplateBinding is used inside control templates and is used to retrieve values from the templated control, in this case the Button).

Up vote 3 down vote favorite 2 share g+ share fb share tw.

I am learning about control templates in WPF and checking out how to replace the button look with custom template styles. I see that to make a circle button, a Ellipse has to be defined with the same height and width. Of course, that only forces all buttons using that style to have a circle with a diameter of 80 pixels, regardless of how the button is resized.

I'd like for the circle to take on the shorter of the height/width values, so that it can dynamically scale according to the button sizing. However I have not read any material that teaches how this can be done in pure XAML template? It seems that some code-behind is required to achieve this effect?

Wpf button styles controltemplate link|improve this question edited Sep 23 '11 at 19:11Dave Clemmer1,77331030 asked Feb 16 '10 at 7:10icelava4,19022050 71% accept rate.

This is where TemplateBinding comes in (TemplateBinding is used inside control templates and is used to retrieve values from the templated control, in this case the Button). Note that this is a shorter form of using: {Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}} The TemplateBinding markup extension is just optimized for only TemplatedParent bindings. That said, if you wanted it to be a circle only, if your ellipse was the smaller of W/H, then your content will easily flow out of it, which I doubt is what you actually want..? I had thought of using a multi value converter to do that, but you can't bind to the converter parameter, so that's out.

In that case, an attached behavior would work, but it's not pretty. ...and the attached behavior: using System; using System.Collections. Generic; using System.

Linq; using System. Text; using System. Windows; namespace WpfApplication1 { public class ConstrainWidthHeight { public static readonly DependencyProperty ConstrainedWidthProperty = DependencyProperty.

RegisterAttached( "ConstrainedWidth", typeof( double ), typeof( ConstrainWidthHeight ), new PropertyMetadata( double. NaN, OnConstrainValuesChanged ) ); public static readonly DependencyProperty ConstrainedHeightProperty = DependencyProperty. RegisterAttached( "ConstrainedHeight", typeof( double ), typeof( ConstrainWidthHeight ), new UIPropertyMetadata( double.

NaN, OnConstrainValuesChanged ) ); public static double GetConstrainedHeight( FrameworkElement obj ) { return (double) obj. GetValue( ConstrainedHeightProperty ); } public static void SetConstrainedHeight( FrameworkElement obj, double value ) { obj. SetValue( ConstrainedHeightProperty, value ); } public static double GetConstrainedWidth( FrameworkElement obj ) { return (double) obj.

GetValue( ConstrainedWidthProperty ); } public static void SetConstrainedWidth( FrameworkElement obj, double value ) { obj. SetValue( ConstrainedWidthProperty, value ); } private static void OnConstrainValuesChanged( object sender, DependencyPropertyChangedEventArgs e ) { FrameworkElement element = sender as FrameworkElement; if( element! = null ) { double width = GetConstrainedWidth( element ); double height = GetConstrainedHeight( element ); if( width!

= double. NaN && height! = double.

NaN ) { double value = Math. Min( width, height ); element. Width = value; element.

Height = value; } } } } } Okay, now the reason why using an attached behavior is required (AFAICT anyway), is that in order to center the ellipse (in a non-square/non-circle scenario), you need the HorizontalAlignment and VerticalAlignment to be able to take effect. The default value of both is Stretch, and when an explicit Width/Height is set, it behaves like Center. With Stretch="Uniform" on, your Ellipse will always physically take up the whole space, it's only the drawing of the Ellipse that will be constrained.

Using this, your drawn Ellipse figure will always start at the top left. So in this case if your button is Wider than it is tall, the drawn portion of the Ellipse won't get centered along with the text. This code is a good example of what you are probably not looking for: ...and the button using it (with a non-square width/height): Looks like this: ... compared to this with the attached property option.

Ok I have tried this method and it seems applying HorizontalAlignment="Center" VerticalAlignment="Center" to the Ellipse also makes the circle shape disappear after resizing to a large size. I wonder what's happening. – icelava Feb 26 '10 at 2:44 Updated my answer to use ActualWidth and ActualHeight.

Binding to W/H is why it's doing what you're seeing. – Adam Sills Feb 26 '10 at 4:53 After changing to ActualWidth and ActualHeight it appears to render in the centre now. Although i'm still haven't fully understood why so, thanks.

– icelava Mar 3 '10 at 3:08.

Set Stretch=Uniform on Ellipse will automatically works like Min(Height,Width) You don't need an attached property as like Adam suggests.

This format works but when I add HorizontalAlignment="Center" VerticalAlignment="Center" to the Ellipse element to centralise it with the ContentPresenter, it disappears. Any ideas? – icelava Feb 18 '10 at 3:02.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions