Именно здесь появляется TemplateBinding (TemplateBinding используется внутри шаблонов элементов управления и используется для извлечения значений из шаблонного элемента управления, в данном случае из кнопки).
<Ellipse Fill="LightGreen"
Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}"/>
Обратите внимание, что это более короткая форма использования:
{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}
Расширение разметки TemplateBinding оптимизировано только для привязок TemplatedParent.
Тем не менее, если вы хотите, чтобы это был только круг, если ваш эллипс был меньше W/H, тогда ваш контент будет легко вытекать из него, что я сомневаюсь, что это то, что вы на самом деле хотите..? Я думал об использовании многозначного преобразователя для этого, но вы не можете привязываться к параметру преобразователя, так что это исключено.
В этом случае привязанное поведение будет работать, но это некрасиво.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:WpfApplication1"
xmlns:local="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300">
<Grid>
<Button Content="Yo!" Width="50" Height="30">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="LightGreen" local:ConstrainWidthHeight.ConstrainedWidth="{TemplateBinding ActualWidth}" local:ConstrainWidthHeight.ConstrainedHeight="{TemplateBinding ActualHeight}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</Window>
... и приложенное поведение:
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;
}
}
}
}
}
Хорошо, теперь причина, по которой требуется использование прикрепленного поведения (во всяком случае, AFAICT), заключается в том, что для центрирования эллипса (в сценарии, отличном от квадрата/не круга) вам нужны HorizontalAlignment и VerticalAlignment, чтобы иметь возможность действовать . Значение по умолчанию для обоих — «Растянуть», и когда задана явная ширина/высота, оно ведет себя как центр.
При включенном Stretch="Uniform" ваш эллипс всегда будет физически занимать все пространство, ограничиваться будет только рисунок эллипса. Используя это, ваша нарисованная фигура Эллипса всегда будет начинаться сверху слева. Таким образом, в этом случае, если ваша кнопка шире, чем высота, нарисованная часть эллипса не будет центрирована вместе с текстом.
Этот код является хорошим примером того, что вы, вероятно, не ищете:
<Ellipse Height="{TemplateBinding ActualHeight}" Width="{TemplateBinding ActualWidth}" Fill="LightGreen" Stretch="Uniform" />
... и кнопка, использующая его (с неквадратной шириной/высотой):
<Button Content="YO!" Style="{StaticResource Button2}" Width="120" Height="53" VerticalAlignment="Top"></Button>
Выглядит так:
http://www.freeimagehosting.net/uploads/84e62c4982.png
... по сравнению с этим с опцией прикрепленного свойства:
http://www.freeimagehosting.net/uploads/40755babcd.png
person
Adam Sills
schedule
17.02.2010