Книги онлайн и без регистрации » Разная литература » Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 334 335 336 337 338 339 340 341 342 ... 407
Перейти на страницу:
SelectedShape _currentShape;

}

В каждом обработчике Click установите переменную-член currentShape в корректное значение SelectedShape:

private void CircleOption_Click(object sender, RoutedEventArgs e)

{

  _currentShape = SelectedShape.Circle;

}

private void RectOption_Click(object sender, RoutedEventArgs e)

{

  _currentShape = SelectedShape.Rectangle;

}

private void LineOption_Click(object sender, RoutedEventArgs e)

{

  _currentShape = SelectedShape.Line;

}

Посредством обработчика события MouseLeftButtonDown элемента Canvas будет визуализироваться подходящая фигура (предопределенного размера) в начальной точке, которая соответствует позиции (х, у) курсора мыши. Ниже приведена полная реализация с последующим анализом:

private void CanvasDrawingArea_MouseLeftButtonDown(object sender,

                                                   MouseButtonEventArgs e)

{

  Shape shapeToRender = null;

  // Сконфигурировать корректную фигуру для рисования.

  switch (_currentShape)

  {

    case SelectedShape.Circle:

      shapeToRender = new Ellipse() { Fill = Brushes.Green,

                                      Height = 35, Width = 35 };

      break;

    case SelectedShape.Rectangle:

      shapeToRender = new Rectangle()

        { Fill = Brushes.Red, Height = 35, Width = 35,

          RadiusX = 10, RadiusY = 10 };

      break;

    case SelectedShape.Line:

      shapeToRender = new Line()

      {

        Stroke = Brushes.Blue,

        StrokeThickness = 10,

        X1 = 0, X2 = 50, Y1 = 0, Y2 = 50,

        StrokeStartLineCap= PenLineCap.Triangle,

        StrokeEndLineCap = PenLineCap.Round

      };

      break;

    default:

      return;

  }

  // Установить левый верхний угол для рисования на холсте.

  Canvas.SetLeft(shapeToRender, e.GetPosition(canvasDrawingArea).X);

  Canvas.SetTop(shapeToRender, e.GetPosition(canvasDrawingArea).Y);

  // Нарисовать фигуру.

  canvasDrawingArea.Children.Add(shapeToRender);

}

На заметку! Возможно, вы заметили, что объекты Ellipse, Rectangle и Line, создаваемые в методе canvasDrawingArea_MouseLeftButtonDown(), имеют те же настройки свойств, что и соответствующие определения XAML. Вполне ожидаемо, код можно упростить, но это требует понимания объектных ресурсов WPF, которые будут рассматриваться в главе 27.

В коде проверяется переменная-член _currentShape с целью создания корректного объекта, производного от Shape. Затем устанавливаются координаты левого верхнего угла внутри Canvas с использованием входного объекта MouseButtonEventArgs. Наконец, в коллекцию объектов UIElement, поддерживаемую Canvas, добавляется новый производный от Shape объект. Если запустить программу прямо сейчас, то она должна позволить щелкать левой кнопкой мыши где угодно на холсте и визуализировать в позиции щелчка выбранную фигуру.

Удаление прямоугольников, эллипсов и линий с поверхности Canvas

Имея в распоряжении элемент Canvas с коллекцией объектов, может возникнуть вопрос: как динамически удалить элемент, скажем, в ответ на щелчок пользователя правой кнопкой мыши на фигуре? Это делается с помощью класса VisualTreeHelper из пространства имен System.Windows.Media. Роль "визуальных деревьев" и "логических деревьев" более подробно объясняется в главе 27, а пока организуйте обработку события MouseRightButtonDown объекта Canvas и реализуйте соответствующий обработчик:

private void CanvasDrawingArea_MouseRightButtonDown(object sender,

                                                    MouseButtonEventArgs e)

{

  // Сначала получить координаты x,y позиции,

  // где пользователь выполнил щелчок.

  Point pt = e.GetPosition((Canvas)sender);

  // Использовать метод HitTestO класса VisualTreeHelper, чтобы

  // выяснить, щелкнул ли пользователь на элементе внутри Canvas.

  HitTestResult result = VisualTreeHelper.HitTest(canvasDrawingArea, pt);

  // Если переменная result не равна null, то щелчок произведен на фигуре.

  if (result != null)

  {

      // Получить фигуру, на которой совершен щелчок, и удалить ее из Canvas.

      canvasDrawingArea.Children.Remove(result.VisualHit as Shape);

  }

}

Метод начинается с получения точных координат (х, у) позиции, где пользователь щелкнул внутри Canvas, и проверки попадания посредством статического метода VisualTreeHelper.HitTest(). Возвращаемое значение — объект HitTestResult — будет установлено в null, если пользователь выполнил щелчок не на UIElement внутри Canvas. Если значение HitTestResult не равно null, тогда с помощью свойства VisualHit можно получить объект UIElement, на котором был совершен щелчок, и привести его к типу, производному от Shape (вспомните, что Canvas может содержать любой UIElement, а не только фигуры). Детали, связанные с "визуальным деревом", будут изложены в главе 27.

На заметку! По умолчанию метод VisualTreeHelper.HitTest() возвращает объект UIElement самого верхнего уровня, на котором совершен щелчок, и не предоставляет информацию о других объектах, расположенных под ним (т.е. перекрытых в Z-порядке).

В результате внесенных модификаций должна появиться возможность добавления фигуры на Canvas щелчком левой кнопкой мыши и ее удаления щелчком правой кнопкой мыши.

До настоящего момента вы применяли объекты типов, производных от Shape, для визуализации содержимого элементов RadioButton с использованием разметки XAML и заполняли Canvas в коде С#. Во время исследования роли кистей и графических трансформаций в данный пример будет добавлена дополнительная функциональность. К слову, в другом примере главы будут иллюстрироваться приемы перетаскивания на объектах UIElement. А пока давайте рассмотрим оставшиеся члены пространства имен System.Windows.Shapes.

Работа с элементами Polyline и Polygon

В текущем примере используются только три класса, производных от Shape. Остальные дочерние классы (Polyline, Polygon и Path) чрезвычайно трудно корректно визуализировать без инструментальной поддержки (такой как инструмент Blend для Visual Studio или другие инструменты, которые могут создавать векторную графику) — просто потому, что они требуют определения большого количества точек для своего выходного представления. Ниже представлен краткий обзор остальных типов Shapes.

Тип Polyline позволяет определить коллекцию координат (х, у) (через свойство Points) для рисования последовательности линейных сегментов, не требующих замыкания. Тип Polygon похож, но запрограммирован так, что всегда замыкает контур, соединяя начальную точку с конечной, и заполняет внутреннюю область с помощью указанной кисти. Предположим, что в редакторе Kaxaml создан следующий элемент StackPanel:

<!-- Элемент Polyline не замыкает автоматически конечные точки -->

<Polyline Stroke ="Red" StrokeThickness ="20" StrokeLineJoin ="Round"

          Points ="10,10 40,40

10,90 300,50"/>

<!-- Элемент Polygon всегда замыкает конечные точки -->

<Polygon Fill ="AliceBlue" StrokeThickness ="5" Stroke ="Green"

          Points ="40,10 70,80

1 ... 334 335 336 337 338 339 340 341 342 ... 407
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. В коментария нецензурная лексика и оскорбления ЗАПРЕЩЕНЫ! Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?