Читайте также:
|
|
Для привязки данных, которая передаёт информацию в объект-источник (режимы TwoWay и OneWayToSource), можно реализовать проверку данных. Если данные не проходят проверку, то источник не обновляется, а пользователь получает визуальный сигнал об ошибке.
Первый способ организации проверки заключается в создании и применении проверочных правил. Каждое проверочное правило – это наследник класса ValidationRuleс переопределённым методом Validate(). Этот метод получает проверяемое значение и информацию о культуре, а возвращает объект ValidationResult с результатом проверки. Ниже приведён пример правила, ограничивающего десятичные значения некоторым диапазоном:
publicclassPositivePriceRule: ValidationRule
{
privatedecimal min = 0;
privatedecimal max = Decimal.MaxValue;
publicdecimal Min
{
get { return min; }
set { min = value; }
}
publicdecimal Max
{
get { return max; }
set { max = value; }
}
publicoverrideValidationResult Validate(object value,
CultureInfo culture)
{
decimal price = 0;
try
{
price = Decimal.Parse((string)value, NumberStyles.Any,
culture);
}
catch
{
returnnewValidationResult(false, "Недопустимыесимволы");
}
if ((price < Min) || (price > Max))
returnnewValidationResult(false, "Внедиапазона");
else
returnnewValidationResult(true, null);
}
}
Проверочные правила помещают в коллекцию ValidationRules, имеющуюся у каждой привязки:
<TextBox>
<TextBox.Text>
<Binding Path="UnitCost" Mode="TwoWay">
<Binding.ValidationRules>
<local:PositivePriceRule Max="999.99"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Второй способ организации проверки основан на генерировании исключительной ситуации в методе установки свойства объекта-источника:
// фрагмент класса: определение свойства UnitCost
publicdecimal UnitCost
{
get { return unitCost; }
set
{
if (value<0)
{
thrownewArgumentException("UnitCost < 0");
}
else
{
unitCost = value;
}
}
}
Исключительные ситуации, возникающие при передаче информации в объект, отлавливаются при помощи специального встроенного проверочного правила ExceptionValidationRule,помещённого в ValidationRules.
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
В качестве альтернативы использованиюExceptionValidationRule можно просто установить свойство привязкиValidatesOnExceptions в значение true.
Третий способ организации проверки данных основан на реализации объектом-источником интерфейса System.ComponentModel.IDataErrorInfo. Интерфейс IDataErrorInfoсодержит два элемента: строковое свойствоError и строковый индексатор с ключом-строкой. Свойство Error– это общее описание ошибок объекта. Индексатор принимает имя свойства и возвращает соответствующую детальную информацию об ошибке. Ключевая идея в том, что вся логика обработки ошибок централизована в индексаторе.
Ниже приведён фрагмент класса, реализующего IDataErrorInfo. В примере проверяется на наличие ошибок только одно свойство.
publicclassProduct: IDataErrorInfo
{
publicstring ModelNumber { get; set; }
// обработкаошибокпроисходитздесь
publicstringthis[string propertyName]
{
get
{
if (propertyName == "ModelNumber"&&
ModelNumber.Any(c =>!Char.IsLetterOrDigit(c)))
return"В ModelNumber допустимы буквы и цифры";
returnnull;
}
}
// WPF не использует это свойство
publicstring Error
{
get { returnnull; }
}
}
Чтобы заставить WPF использовать интерфейс IDataErrorInfo и применять его для проверки ошибок при модификации свойства, нужно добавить встроенное правило DataErrorValidationRuleв коллекцию ValidationRules:
<Binding.ValidationRules>
<DataErrorValidationRule />
</Binding.ValidationRules>
В качестве альтернативы использованиюDataErrorValidationRule можно установить свойство привязкиValidatesOnDataErrors в значение true.
При нарушении любого из проверочных правил, инфраструктура WPFвыполняет следующие шаги:
· В целевом элементеприсоединённое свойствоValidation.HasError устанавливается в true.
· Создаётся объект ValidationError с информацией об ошибке и добавляется в присоединённую коллекцию Validation.Errors.
· Если свойство привязки NotifyOnValidationError установлено в true, WPF инициирует в целевом элементе присоединённое событие Validation.Error.
Визуальное представление целевого элемента управления также изменяется при возникновении ошибки. Шаблон элемента заменяется шаблоном, определённым в свойстве Validation.ErrorTemplate. Например, в текстовом поле новый шаблон окрашивает контур рамки в красный цвет.
8. Фигуры
Фигуры – это элементы WPF, представляющие простые линии, эллипсы, прямоугольники и многоугольники. Все фигуры наследуются от абстрактного класса System.Windows.Shapes.Shape. Этот класс определяет небольшой набор важных свойств, перечисленных в табл. 6.
Таблица 6
Свойства класса Shape
Имя | Описание |
Fill | Кисть (объект Brush), рисующая поверхность фигуры |
Stroke | Кисть, рисующаяграницу фигуры |
StrokeThickness | Шириналинии в единицахWPF. При рисовании линии её ширина разбивается поровну на каждую сторону[14] |
StrokeStartLineCap,StrokeEndLineCap | Контур начала и конца линии. Эти свойства имеют эффект для фигур Line, Polyline и (иногда) Path |
StrokeDashArray, StrokeDashOffset, StrokeDashCap | Свойства позволяют создавать пунктир. Можно управлять размером и частотой пунктира, а также контуром, ограничивающим начало и конец каждого фрагмента пунктира |
StrokeLineJoin, StrokeMiterLimit | Контур углов фигуры (свойства затрагивают вершины, где стыкуются разные линии) |
Stretch | Способ заполнения фигурой доступного пространства |
DefiningGeometry | Представляет геометрию фигуры (объект Geometry). Объект Geometry описывает координаты и размер фигуры без учёта таких вещей из UIElement, как поддержка событий клавиатуры и мыши |
GeometryTransform | Позволяет применить к фигуре трансформацию (объект Transform) |
RenderedGeometry | Геометрия, описывающая подготовленную к отображению фигуру |
Перейдём к рассмотрению конкретных фигур. Rectangle и Ellipse представляют прямоугольник и эллипс.Размеры этих фигур определяются свойствами Height и Width, а свойстваFill и Stroke делают фигуру видимой[15]. Класс Rectangleимеет свойства RadiusX и RadiusYдля создания закруглённых углов (RadiusX и RadiusYможно воспринимать как полуоси эллипса, используемого для размещения в углах прямоугольника).
<Rectangle Canvas.Top="10" Canvas.Left="10" Height="80" Width="120"
Fill="Azure" Stroke="Coral" RadiusX="30" RadiusY="20" />
<Ellipse Canvas.Bottom="10" Canvas.Right="10" Height="60" Width="80"
Fill="Aqua" Stroke="Olive" StrokeThickness="6" />
<Rectangle Canvas.Top="20" Canvas.Left="150" Height="80" Width="220"
Stroke="Green" StrokeThickness="14"
StrokeLineJoin="Bevel" StrokeMiterLimit="10" />
Рис. 24.Прямоугольники и эллипс.
Фигура Line– это отрезок, соединяющий две точки. Начальная и конечная точки устанавливаются свойствами X1 и Y1 (для первой точки) и X2 и Y2 (для второй точки). Координаты отрезка отсчитываются относительно верхнего левого угла контейнера, в котором он содержится. Если отрезок рисуется в Canvas, установка свойств позиции задаст смещение координатной системы рисования. Чтобы сделать отрезок видимым, нужно задать свойство Stroke:
<LineStroke="Blue"X1="0"Y1="0"X2="10"Y2="100" />
Класс Polyline позволяет рисовать последовательность связанных отрезков. Для этого необходимо задать набор точек в свойстве-коллекции Points. В XAML для Pointsможно использовать лаконичный строчный синтаксис, просто перечислив точки координат через пробел или запятую. Класс Polygonнапоминает Polyline. При рисовании этот элемент добавляет финальный отрезок, соединяющий начальную и конечную точки коллекции Points.
<Polygon Stroke="Blue" StrokeThickness="5"
Points="90,80 110,120 130,180 150,110 170,190 190,100 210,240" />
Рисуя фигуры Line и Polyline, можно указать форму начальной и конечной точки линии, используя свойства StartLineCap и EndLineCap. Изначально эти свойства установлены в Flat, что означает немедленное завершение линии в её конечных координатах. К другим возможным вариантам относятся Round (линия мягко закругляется). Triangle (сводит обе стороны линии в точку) и Square (завершает линию чёткой гранью). Все значения, кроме Flat, добавляют линии длину–половину толщины линиидополнительно.
<Line X1="30" Y1="30" X2="200" Y2="30" Stroke="Brown"StrokeThickness="20"
StrokeStartLineCap="Triangle"StrokeEndLineCap="Round" />
ВсефигурыпозволяютизменятьвидиформусвоихугловчерезсвойствоStrokeLineJoin. Значение по умолчанию –Miter– использует чёткие грани, Bevel обрезает угол в точке сопряжения, аRound– плавно закругляет его.
<Polyline Stroke="Blue" StrokeThickness="5" StrokeLineJoin="Round"
Points="60,140 80,90 100,150 120,90 140,140"/>
Линии (включая границы фигур) могут быть изображены пунктиром. При этом в свойстве-массивеStrokeDashArrayуказываютсядлины сплошных и прерванных сегментов (пробелов). Эти значения интерпретируются относительно толщины линии.
<RectangleCanvas.Top="20"Canvas.Left="230"Height="120"Width="40"
StrokeThickness="4"StrokeDashArray="2 1.5"Stroke="Navy"/>
Рис. 25.Концы линий, форма углов и штриховка.
Фигура Pathпредназначена для отображения произвольной геометрии[16]. Этот класс имеет свойство Dataс типом Geometry. При задании Dataиспользуется один из наследников класса Geometry:
· RectangleGeometry–прямоугольник;геометрический эквивалент фигуры Rectangle.
· EllipseGeometry– эллипс;геометрический эквивалент Ellipse.
· LineGeometry–прямая линия; геометрический эквивалент Line.
· GeometryGroup –связывает набор объектов Geometryв единый путь.
· CombinedGeometry– объединяет две геометрии в единую фигуру, при этом можно указать способ комбинирования составляющих.
· PathGeometry–сложная фигура, состоящая из дуг, кривых и линий.
· StreamGeometry– неизменяемый облегченный эквивалент PathGeometry.
Классы LineGeometry, RectangleGeometry и EllipseGeometry отображаются непосредственно на фигуры Line,Rectangle и Ellipse.Ниже для сравнения приведены эквивалентные фрагменты разметок:
<RectangleFill="Yellow"Stroke="Blue"Width="100"Height="50" />
<!--эквивалентно-->
<Path Fill="Yellow" Stroke="Blue">
<Path.Data>
<RectangleGeometry Rect="0,0 100,50" />
</Path.Data>
</Path>
<Line Stroke="Blue" X1="0" Y1="0" X2="10" Y2="100" />
<!--эквивалентно-->
<Path Fill="Yellow" Stroke="Blue">
<Path.Data>
<LineGeometry StartPoint="0,0" EndPoint=" 10,100" />
</Path.Data>
</Path>
<Ellipse Fill="Yellow" Stroke="Blue" Width="100" Height="50" />
<!--эквивалентно-->
<Path Fill="Yellow" Stroke="Blue">
<Path.Data>
<EllipseGeometry RadiusX="50" RadiusY="25" Center="50,25" />
</Path.Data>
</Path>
Класс GeometryGroup предоставляет возможность для объединения нескольких геометрий в единое целое. В следующем примере при помощиGeometryGroup создаётся фигура в виде квадрата с отверстием:
<Canvas>
<TextBlock Canvas.Top="50" Canvas.Left="20" FontSize="25"
FontWeight="Bold" Text="Hello There" />
<Path Fill="Yellow" Stroke="Blue" Margin="5"
Canvas.Top="10" Canvas.Left="10">
<Path.Data>
<GeometryGroup>
<RectangleGeometry Rect="0,0 100,100" />
<EllipseGeometry Center="50,50"
RadiusX="35" RadiusY="25" />
</GeometryGroup>
</Path.Data>
</Path>
</Canvas>
Рис. 26.Демонстрация GeometryGroup.
GeometryGroup отлично работает при создании фигур посредством рисования одной и последующего «вычитания» другой изнутри первой.Для сложных случаев совмещения фигур предназначен класс CombinedGeometry. Он принимает две геометрии в свойствах Geometry1 и Geometry2и комбинирует их способом, указанным в свойстве GeometryCombineMode(имеющем тип одноимённого перечисления):
· Union– объединение геометрий;
· Intersect– пересечение геометрий;
· Exclude– исключение из первой геометрии второй геометрии;
· Xor– объединение геометрий, из которого исключено их пересечение.
Ниже приведён фрагмент разметки, демонстрирующий объединение геометрий, и рисунок, показывающий все четыре способа комбинирования.
<Path Fill="Gold" Stroke="Blue" Margin="5">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Union">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0 100, 100" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry Center="85,50"
RadiusX="65" RadiusY="35" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
Рис. 27.Четыре способа комбинирования геометрий.
Класс PathGeometryописывает геометрию при помощи объектов PathFigure, хранящихся в коллекции PathGeometry.Figures.PathFigure– это непрерывный набор связанных отрезков и кривых линий. У класса PathFigureчетыре ключевых свойства:
1. StartPoint– точка (объект Point) начала первой линии фигуры.
2. Segments– коллекция объектов PathSegment, используемых для рисования фигуры.
3. IsClosed–если установлено в true, то добавляется отрезок, соединяющий начальную и конечную точкиPathFigure (если они не совпадают).
4. IsFilled–если установлено в true, то область внутри фигуры заполняется кистью Path.Fill.
Есть несколько типов сегментов, унаследованных от класса PathSegment:
· LineSegment–отрезок;
· ArcSegment–эллиптическая дуга;
· BezierSegment–кривая Безье[17];
· QuadraticBezierSegment–упрощённаяквадратичнаякривая Безье, имеющая одну контрольную точку вместо двух;
· PolyLineSegment–серияотрезков;
· PolyBezierSegment–серия кривых Безье.
· PolyQuadraticBezierSegment–серияупрощённых кривых Безье.
Использование объектов PathGeometry, PathFigure, PathSegment при описании сложной геометрии может быть чрезвычайно многословно. В WPF имеется краткий альтернативный синтаксис, которые позволяет представить детализированные фигуры в меньшем объёме кода разметки. Этот синтаксис называют геометрическим мини-языком.
Выражениягеометрического мини-языка – это строки, содержащие серии команд. Каждая команда – это одна буква, за которой необязательно следуют несколько параметров (например, координаты). Команда отделяется пробелом. В табл. 7 перечислены все команды геометрического мини-языка.
Таблица 7
Команды геометрического мини-языка[18]
Команда, параметры | Описание |
F значение | Устанавливает свойство Geometry.FillRule – правило «заливки» контура (0 для EvenOdd или 1 для NonZero). Эта команда должна стоять в начале строки (если она вообще будет применяться) |
M x, y | Устанавливает начальную точку PathFigure. Любое выражение геометрического языка начинается либо с команды M, либо с пары команд Fи M.Команда Mвнутри выражения служит для перемещения начала координатной системы |
L x, y | Создаёт LineSegment до указанной точки |
H x | Создаёт горизонтальный отрезок до указанного значения x |
V y | Создаёт вертикальный отрезок до указанного значения y |
A radiusX, radiusY degreesisLargeArc isClockwisex, y | Создаёт ArcSegment до заданной точки. Указываются радиусы эллипса, описывающего дугу, угол дуги в градусах и булевские флагинастройки дуги |
C x1, y1x2, y2x, y | СоздаётBezierSegment до указанной точки, используя контрольные точки x1, y1 и x2, y2 |
Q x1, y1x, y | СоздаётQuadraticBezierSegment до указанной точки, с одной контрольной точкой x1, y1 |
S x1, y1x, y | СоздаётгладкийBezierSegment до указанной точки, с одной контрольной точкой x1, y1 |
Z | Завершает текущую PathFigure и устанавливает IsClosed в true |
Следующая разметка определяет фигуру в виде треугольника:
<Path Stroke="Blue">
<Path.Data>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="10,100">
<LineSegment Point="100,100" />
<LineSegment Point="100,50" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
Чтобы нарисовать тот же треугольник при помощи геометрического мини-языка, нужна такая разметка:
<Path Stroke="Blue" Data="M 10,100 L 100,100 L 100,50 Z" />
9. Цвет,кисти, прозрачность
Дата добавления: 2015-11-14; просмотров: 38 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Конвертеры значений | | | Представление цвета в WPF |