Đây là nơi TemplateBinding xuất hiện (TemplateBinding được sử dụng bên trong mẫu điều khiển và được sử dụng để truy xuất các giá trị từ điều khiển khuôn mẫu, trong trường hợp này là Nút).
<Ellipse Fill="LightGreen"
Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}"/>
Lưu ý rằng đây là một hình thức ngắn hơn của việc sử dụng:
{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}}
Phần mở rộng đánh dấu TemplateBinding chỉ được tối ưu hóa cho chỉ bindings TemplatedParent.
Điều đó nói rằng, nếu bạn muốn nó chỉ là một vòng tròn, nếu hình elip của bạn nhỏ hơn W/H, thì nội dung của bạn sẽ dễ dàng thoát ra khỏi nó, mà tôi nghi ngờ là những gì bạn thực sự muốn ..? Tôi đã nghĩ đến việc sử dụng một bộ chuyển đổi giá trị đa để làm điều đó, nhưng bạn không thể liên kết với thông số chuyển đổi, vì vậy đó là ra ngoài.
Trong trường hợp đó, hành vi được đính kèm sẽ hoạt động nhưng không đẹp.
<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>
... và hành vi kèm theo:
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;
}
}
}
}
}
rồi, bây giờ lý do tại sao bằng cách sử dụng một hành vi gắn được yêu cầu (AFAICT anyway), là nhằm tập trung các hình elip (trong một trường hợp không vuông/không phải vòng tròn), bạn cần HorizontalAlignment và VerticalAlignment để có thể có hiệu lực. Giá trị mặc định của cả hai là Stretch và khi một Chiều rộng/Chiều cao rõ ràng được đặt, nó hoạt động như Trung tâm.
Với Stretch = "Uniform" bật, Ellipse của bạn sẽ luôn luôn chiếm lĩnh toàn bộ không gian, nó chỉ là bản vẽ của Ellipse sẽ bị hạn chế. Sử dụng hình này, hình Ellipse được vẽ của bạn sẽ luôn bắt đầu ở trên cùng bên trái. Vì vậy, trong trường hợp này nếu nút của bạn là Rộng hơn là cao, phần được vẽ của Ellipse sẽ không được căn giữa cùng với văn bản.
Mã này là một ví dụ tốt về những gì bạn đang có lẽ không tìm kiếm
<Ellipse Height="{TemplateBinding ActualHeight}" Width="{TemplateBinding ActualWidth}" Fill="LightGreen" Stretch="Uniform" />
... và nút sử dụng nó (có chiều rộng không vuông/chiều cao):
<Button Content="YO!" Style="{StaticResource Button2}" Width="120" Height="53" VerticalAlignment="Top"></Button>
Trông như thế này:
Ugly http://www.freeimagehosting.net/uploads/84e62c4982.png
...so với này với tùy chọn tài sản gắn liền:
alt text http://www.freeimagehosting.net/uploads/40755babcd.png
ok tôi đã thử phương pháp này và có vẻ như áp dụng HorizontalAlignment = "Trung tâm" VerticalAlignment = "Trung tâm" để Ellipse cũng làm cho hình dạng vòng tròn biến mất sau khi thay đổi kích thước để một lớn kích thước. Tôi tự hỏi chuyện gì đang xảy ra. – icelava
Đã cập nhật câu trả lời của tôi để sử dụng ActualWidth và ActualHeight. Ràng buộc để W/H là lý do tại sao nó đang làm những gì bạn đang nhìn thấy. –
Sau khi chuyển sang ActualWidth và ActualHeight, nó xuất hiện để hiển thị ở trung tâm ngay bây giờ. Mặc dù tôi vẫn chưa hiểu hết tại sao vậy, cảm ơn. – icelava