레이블의 여백을 레이블의 ActualWidth
및 ActualHeight
에 바인딩하고이 값에 -0.5를 곱하면됩니다. 그러면 라벨이 너비의 절반만큼 왼쪽으로 이동합니다. 라벨을 반 높이만큼 위로 움직입니다. 여기
은 예이다 :
XAML :
<Window x:Class="CenteredLabelTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CenteredLabelTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:CenterConverter x:Key="centerConverter"/>
</Window.Resources>
<Canvas>
<TextBlock x:Name="txt" Canvas.Left="40" Canvas.Top="40" TextAlignment="Center" Text="MMMMMM">
<TextBlock.Margin>
<MultiBinding Converter="{StaticResource centerConverter}">
<Binding ElementName="txt" Path="ActualWidth"/>
<Binding ElementName="txt" Path="ActualHeight"/>
</MultiBinding>
</TextBlock.Margin>
</TextBlock>
<Rectangle Canvas.Left="39" Canvas.Top="39" Width="2" Height="2" Fill="Red"/>
</Canvas>
</Window>
붉은 사각형 하이라이트 좌표 (40, 40)의 라벨 "MMMMMM"가 중심이되는.
변환기 : 결과는 다음과 같습니다
public class CenterConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] == DependencyProperty.UnsetValue || values[1] == DependencyProperty.UnsetValue)
{
return DependencyProperty.UnsetValue;
}
double width = (double) values[0];
double height = (double)values[1];
return new Thickness(-width/2, -height/2, 0, 0);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
는 :
public class Mover : DependencyObject
{
public static readonly DependencyProperty MoveToMiddleProperty =
DependencyProperty.RegisterAttached("MoveToMiddle", typeof (bool), typeof (Mover),
new PropertyMetadata(false, PropertyChangedCallback));
public static void SetMoveToMiddle(UIElement element, bool value)
{
element.SetValue(MoveToMiddleProperty, value);
}
public static bool GetMoveToMiddle(UIElement element)
{
return (bool) element.GetValue(MoveToMiddleProperty);
}
private static void PropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element == null)
{
return;
}
if ((bool)e.NewValue)
{
MultiBinding multiBinding = new MultiBinding();
multiBinding.Converter = new CenterConverter();
multiBinding.Bindings.Add(new Binding("ActualWidth") {Source = element});
multiBinding.Bindings.Add(new Binding("ActualHeight") {Source = element});
element.SetBinding(FrameworkElement.MarginProperty, multiBinding);
}
else
{
element.ClearValue(FrameworkElement.MarginProperty);
}
}
}
:
프로그래밍 그렇게하기 위해이 같은 연결된 속성 Mover.MoveToMiddle
을 정의
설정 Mover.MoveToMiddle
에서 true
은 해당 프레임 워크 요소의 여백이 실제 너비와 높이에 자동으로 바인딩되어 프레임 워크 요소가 해당 중심점으로 이동한다는 것을 의미합니다.
이 같이 당신의 XAML 코드를 사용합니다 :
<Window x:Class="CenteredLabelTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CenteredLabelTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:CenterConverter x:Key="centerConverter"/>
</Window.Resources>
<Canvas>
<TextBlock Canvas.Left="40" Canvas.Top="40" TextAlignment="Center" Text="MMMMMM"
local:Mover.MoveToMiddle="True"/>
<Rectangle Canvas.Left="39" Canvas.Top="39" Width="2" Height="2" Fill="Red"/>
</Canvas>
</Window>
대안은 RenderTransform
대신 Margin
에 결합하는 것입니다. 이 경우, 컨버터는
return new TranslateTransform(-width/2, -height/2);
을 반환과 연결된 속성의 콜백 메소드는이 라인을 포함됩니다 :
if ((bool)e.NewValue)
{
...
element.SetBinding(UIElement.RenderTransformProperty, multiBinding);
}
else
{
element.ClearValue(UIElement.RenderTransformProperty);
}
이 대안이 연결된 속성의 효과는 시각에서 볼 수있는 장점이있다을 Studio 디자이너 (Margin 속성을 설정할 때 해당하지 않음)
사람들 "PresentationCore.dll \ 참조 어셈블리 \ 마이크로 소프트 \ 프레임 워크 \ 3.0 이 답을 살펴보고 질문의 간단한 요구 사항에 대해 너무 복잡하다고 생각할 수도 있지만, 이는 레이블을 가운데에 배치하는 방법을 보여주는 것이 아닙니다. 이 코드는 포인트에 'FrameworkElement'를 중점에 배치하고 요소의 크기가 변경 될 때라도 중앙에 유지하는 동작을 정의합니다. –
정말 잘 작동합니다. XAML에서 사용법은 다음과 같습니다. "100,100"을 Point로 자동 변환합니다. –
비 WPF XAML에서도 완벽하게 작동합니다. Windows 10 universal, 감사합니다! –