Чтение онлайн

ЖАНРЫ

C# для профессионалов. Том II

Ватсон Карли

Шрифт:

Чтобы перейти из точки А в точку В, необходимо сместиться на 20 единиц вправо и на 10 единиц вниз, помеченных как X и Y на рисунке, так как это обычное обозначение. Можно было бы создать структуру

Point
, которая представляет это, следующим образом:

Point АВ = new Point(20, 10);

Console.WriteLine("Moved {0} across, {1} down", AB.X, AB.Y);

X и Y являются свойствами чтения-записи, а значит, можно также задать значения в

Point
следующим образом:

Point АВ = new Point;

AB.X = 20;

АВ.Y = 10;

Console.WriteLine("Moved (0) across, (1) down", AB.X, AB.Y);

Отметим,

что хотя обычно горизонтальные и вертикальные координаты обозначаются как координаты х и у (буквы нижнего регистра), соответствующие свойства
Point
обозначаются
X
и
Y
(буквами верхнего регистра), так как обычное соглашение в C# для открытых свойств требует, чтобы их имена начинались с букв верхнего регистра.

PointF
по сути идентична
Point
, за исключением того, что
X
и
Y
имеют тип
float
вместо
int
.
PointF
используется, когда координаты не обязательно являются целыми значениями. Для этих структур определено преобразование типов, поэтому можно неявно преобразовывать из
Point
в
PointF
и явно из
PointF
в
Point
(последнее преобразование явное в связи с риском ошибок округления):

PointF ABFloat = new PointF(20.5F, 10.9F);

Point AB = (Point)ABFloat;

PointF ABFloat2 = AB;

Одно последнее замечание о координатах. В нашем обсуждении

Point
и
PointF
сознательно присутствует неопределенность в отношении единиц измерения. Можно говорить о 20 пикселях вправо и 10 пикселях вниз или о 20 дюймах, или 20 милях. Интерпретация координат полностью принадлежит разработчику.

По умолчанию GDI+ будет представлять единицы измерения как пиксели на экране (или принтере, в зависимости от графического устройства), именно таким образом методы объекта

Graphics
будут представлять любые координаты, которые передаются им в качестве параметров. Например, точка
Point(20, 10)
представляет 20 пикселей вправо по экрану и 10 пикселей вниз. Обычно эти пиксели измеряются от верхнего левого угла клиентской области окна, как было до сих пор в рассмотренных примерах. Но это не всегда так, в некоторых ситуациях может потребоваться нарисовать относительно верхнего левого угла всего окна (включая границу) или даже относительно верхнего левого угла экрана. В большинстве случаев, однако, если документация не говорит обратное, можно предполагать, что речь идет о пикселях относительно верхнего левого угла клиентской области.

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

Size и SizeF

Подобно

Point
и
PointF
размеры выступают в двух вариантах. Структура
Size
предназначена для работы с целыми значениями,
SizeF
— для значений с плавающей точкой. В остальном
Size
и
SizeF
идентичны. Мы сосредоточимся здесь на структуре
Size
.

Во многом

Size
аналогична структуре
Point
. Она имеет два целых свойства, которые представляют горизонтальное и вертикальное расстояния, основное различие состоит в том, что вместо
X
и
Y
эти свойства называются
Width
и
Height
. Можно представить предыдущую диаграмму с помощью кода:

Size АВ = new Size(20, 10);

Console.WriteLine("Moved {0} across, {1} down", AB.Width, AB.Height);

Строго говоря структура

Size
математически представляет то же, что и
Point
, но концептуально она предназначена для использования немного другим образом.
Point
применяется, если говорится о местоположении объекта, a
Size
— когда речь идет о размере чего-то.

В качестве примера рассмотрим нарисованный ранее прямоугольник с координатой вверху слева (0, 0) и размером (50, 50):

Graphics dc. = е.Graphics;

Pen BluePen = new Pen(Color.Blue, 3);

dc.Rectangle(BluePen, 0, 0, 50, 50);

Размер этого прямоугольника равен (50, 50) и может быть представлен экземпляром

Size
. Нижний правый угол также находится в точке (50, 50), но будет представляться экземпляром
Point
. Чтобы увидеть различия, предположим, что мы рисуем прямоугольник в другом месте, так что его верхняя левая координата будет (10, 10).

dc.DrawRectangle(BluePen, 10, 10, 50, 50);

Теперь нижний правый угол имеет координаты (60, 60), но размер не изменился — по-прежнему (50, 50).

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

static void Main(string [] args) {

 Point TopLeft = new Point (10, 10);

 Size RectangleSize = new Size(50, 50);

 Point BottomRight = TopLeft + RectangleSize;

 Console.WriteLine("TopLeft = " + TopLeft);

 Console.WriteLine("BottomRight = " + BottomRight);

 Console.WriteLine("Size = " + RectangleSize);

}

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

Отметим, что этот вывод показывает также, как метод

ToString
объектов
Point
и
Size
был переопределен для вывода значения в формате {X, Y}.

Аналогично можно вычесть

Size
из
Point
, чтобы задать
Point
, или складывать два размера
Size
, задавая другой размер
Size
. Однако невозможно сложить точку
Point
с другой точкой
Point
. Компания Microsoft определила, что такое действие не имеет концептуального смысла, поэтому было решено не создавать никакою перезагружаемого оператора + который бы позволял это сделать.

Можно также явно преобразовать

Point
в
Size
и наоборот:

Point TopLeft = new Point(10, 10);

Size S1 = (Size)TopLeft;

Point P1 = (Point)S1;

При этом преобразовании значению

S1.Width
присваивается значение
TopLeft.X
, а
S1.Height
TopLeft.Y
. Следовательно,
S1
содержит (10, 10).
P1
будет содержать те же значения, что и
TopLeft
.

Поделиться с друзьями: