Центрирование многоугольника в элементе управления Grid - PullRequest
5 голосов
/ 21 сентября 2010

Может кто-нибудь сказать мне, как центрировать объект многоугольника в данной строке / столбце элемента управления Grid?

Пример, который я пробовал, взят из msdn.

<Grid x:Name="LayoutRoot" >
  <Polygon Points="300,200 400,125 400,275 300,200" 
           Stroke="Purple" 
           StrokeThickness="2"
           HorizontalAlignment="Center"
           VerticalAlignment="Center" >
    <Polygon.Fill>
        <SolidColorBrush Color="Blue" Opacity="0.4" />
    </Polygon.Fill>
 </Polygon>

Приветствия

Xam

Ответы [ 3 ]

3 голосов
/ 21 сентября 2010

Добавьте атрибуты: -

 HorizontalAlignment="Center" VerticalAlignment="Center"

в Polygon.

0 голосов
/ 30 августа 2018

Может быть этот ответ применяется и здесь.

Он использует CenterConverter

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();
    }
}

И связывает его в XAML следующим образом

<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>

Чтобы иметь возможность использовать это и в C #, и не только в XAML, вам нужен этот класс

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);
        }
    }

}

Используйте его в XAML, например

<Canvas>
    <TextBlock Canvas.Left="40" Canvas.Top="40" TextAlignment="Center" Text="MMMMMM"
          local:Mover.MoveToMiddle="True"/>
</Canvas>

Или в C #, например

Mover.SetMoveToMiddle(UIElement, true);

В качестве альтернативы вы можете манипулировать RenderTransform

Альтернативой может быть привязка к RenderTransform вместо Margin.В этом случае преобразователь вернет

return new TranslateTransform(-width / 2, -height / 2);

, а метод обратного вызова присоединенного свойства будет содержать следующие строки:

if ((bool)e.NewValue)
{
    ...
    element.SetBinding(UIElement.RenderTransformProperty, multiBinding);
}
else
{
    element.ClearValue(UIElement.RenderTransformProperty);
}

ThisПреимущество альтернативы заключается в том, что эффект присоединенного свойства виден в конструкторе Visual Studio (а это не так при установке свойства Margin).

В XAML это будет выглядеть так:

<Canvas>
    <TextBlock x:Name="txt" Canvas.Left="40" Canvas.Top="40" TextAlignment="Center" Text="MMMMMM">
        <TextBlock.RenderTransform>
            <MultiBinding Converter="{StaticResource centerConverter}">
                    <Binding ElementName="txt" Path="ActualWidth"/>
                    <Binding ElementName="txt" Path="ActualHeight"/>
            </MultiBinding>
        </TextBlock.RenderTransform>
    </TextBlock>
    <Rectangle Canvas.Left="39" Canvas.Top="39" Width="2" Height="2" Fill="Red"/>
</Canvas>

TextBlock был контрольным вопросом исходного ответа.Этот способ должен быть применим ко всем объектам класса UIElement .

Примечание: все данные относятся к оригинальному постеру вышеуказанного связанного ответа

0 голосов
/ 21 сентября 2010

Хотя высота и ширина подразумеваются границами многоугольника, он по умолчанию равен размеру контейнера.

Если вы просто установите

HorizontalAlignment="Center" VerticalAlignment="Center"

, он установит многоугольниквверху слева в центре.

Вы также должны явно установить высоту и ширину многоугольника, чтобы центрировать его и сохранить его границы

Пример полигона Xaml с добавленными размерами:

<Grid x:Name="LayoutRoot">
   <Path Data="M0.5,41.5 L201,0.5 L302,115 L157.25,157 z" Fill="#FFF4F4F5" Stroke="Black" UseLayoutRounding="False" HorizontalAlignment="Center" VerticalAlignment="Center" Width="302.5" Height="157.5"/>
</Grid>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...