Проблемы с рисованием буквы «x» в центре круга с помощью XAML

#wpf #xaml

#wpf #xaml

Вопрос:

Я пытаюсь создать красный круг с черным крестом через него, используя XAML.
Моя проблема в том, что они не выровнены правильно.
Как правильно это сделать?

Это то, что у меня пока есть:

   <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Image>
    <Image.Source>
      <DrawingImage>
        <DrawingImage.Drawing>
          <DrawingGroup>
            <GeometryDrawing Brush="Red">
              <GeometryDrawing.Pen>
                <Pen Brush="Transparent" Thickness="0"/>
              </GeometryDrawing.Pen>
              <GeometryDrawing.Geometry>
                <EllipseGeometry Center="8,8" RadiusX="8" RadiusY="8"/>
              </GeometryDrawing.Geometry>
            </GeometryDrawing>
            <GeometryDrawing>
              <GeometryDrawing.Pen>
                <Pen Brush="Black" Thickness="2.5"/>
              </GeometryDrawing.Pen>
              <GeometryDrawing.Geometry>
                <PathGeometry>
                  <PathFigure StartPoint="4,4">
                    <LineSegment Point="12,12"/>
                  </PathFigure>
                  <PathFigure StartPoint="4,12">
                    <LineSegment Point="12,4"/>
                  </PathFigure>
                </PathGeometry>
              </GeometryDrawing.Geometry>
            </GeometryDrawing>
          </DrawingGroup>
        </DrawingImage.Drawing>
      </DrawingImage>
    </Image.Source>
    </Image>
  </Grid>
  

Просто поместив эллипс в ту же сетку с черным крестиком, крест не совсем центрирован на эллипсе, потому что координаты каждой нарисованной вами линии на самом деле являются координатами в отведенном для нее пространстве.

Я думаю, что им нужно было иметь какую-то геометрию или агрегат для рисования, чтобы дать им одну и ту же систему координат. Геометрическая группа и контур являются агрегаторами, но оба требуют, чтобы их содержимое имело одинаковую заливку и обводку, а обводка и заливка различны для красного круга (без обводки) и черного X (без заливки).

Единственным агрегатором, который предоставляет общие системы координат и допускает различные заливки и штрихи для своих членов, который я смог найти, была DrawingGroup.

Ярлыки строк, которые работают для создания пути через его свойство Data, похоже, не работают для создания PathGeometry, поэтому все пришлось заполнять вручную.

Комментарии:

1. Я думаю, что в этом случае я бы просто использовал обычное изображение.

2. лол. Да, если это действительно xaml-способ сделать это, png ОПРЕДЕЛЕННО подойдет. У меня только что вошло в привычку выполнять небольшие графические операции в xaml, потому что в нем было так легко изменять размер, перекрашивать, использовать мягкие градиенты и т.д…

Ответ №1:

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

     <Grid HorizontalAlignment="Left" 
          Height="80" 
          Margin="80,80,0,0" 
          VerticalAlignment="Top" 
          Width="80">
        <Ellipse Fill="Red"
                 HorizontalAlignment="Stretch"
                 VerticalAlignment="Stretch" />
        <Path Data="M40,53 L48,69 62,69 49,46 61,24 48,24 C48,24 40,39 40,39 40,39 32,24 32,24 L18,24 30,46 17,69 31,69 z" 
              Fill="Black" 
              Margin="15" 
              Stretch="Fill" 
              HorizontalAlignment="Center"
              VerticalAlignment="Center"
              />
    </Grid>
  

Вероятно, это не совсем то, что вы ищете, но, надеюсь, это, по крайней мере, дает вам другой способ подумать об этом.

Комментарии:

1. Это было первое, что я попробовал, за исключением того, что для эллипса были установлены определенные размеры, а для выравнивания по горизонтали и вертикали — по центру как для эллипса, так и для контура. С этими настройками крест не совсем центрирован на эллипсе (просто немного смещен, но слишком заметен, чтобы включать). Я проверю ваш вариант.

2. Очень приятно. Выравнивание отличается от того, что я изначально пробовал, и от того, что содержится в вашем ответе, потому что вы центрировали свой крест, установив значение Stretch в «Fill» и используя margin, чтобы сохранить его в границах, и использовали тот же механизм для центрирования вашего эллипса. Отлично сделано.

Ответ №2:

У меня была такая же проблема при попытке центрировать текст внутри эллипса. Проблема с использованием чего-то вроде TextBlock заключается в том, что кернинг и экранирование каждого символа немного отличаются, и поэтому, хотя сам элемент TextBlock технически может быть центрирован внутри эллипса, это не означает, что символ будет центрирован в эллипсе. В большинстве ситуаций символ всегда находится слишком низко и справа от центра.

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

Мне также, кажется, больше повезло с использованием внешнего элемента нечетной ширины / высоты, а не четной ширины и высоты.

                 <Grid Width="19"
                      Height="19">
                    <Ellipse Fill="#FFB1413F"
                             StrokeThickness="0"
                             HorizontalAlignment="Stretch"
                             VerticalAlignment="Stretch" />
                    <Viewbox HorizontalAlignment="Center"
                             VerticalAlignment="Stretch">
                        <TextBlock Text="X"
                                   Margin="1"
                                   FontWeight="Bold"
                                   Foreground="White"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center" />
                    </Viewbox>
                </Grid>