Автор работы: Пользователь скрыл имя, 11 Мая 2012 в 22:14, реферат
В WPF используется особая разновидность графической визуализации, которая называется графикой сохраненного режима (retained-mode). Это означает, что в случае использования XAML-разметки или процедурного кода для генерации графической визуализации, за сохранение этих визуальных элементов и обеспечение их корректной перерисовки и обновления в оптимальной манере отвечает WPF. Поэтому визуализируемые графические данные постоянно присутствуют, даже когда конечный пользователь скрывает изображение, перемещая или сворачивая окно, перекрывая одно окно другим и т.д.
Графические возможности платформы .NET
В языке C# на платформе .NET 4 графикой управляет так называемая WPF (Windows Presentation Foundation) – служба графической визуализации.
В WPF используется особая разновидность графической визуализации, которая называется графикой сохраненного режима (retained-mode). Это означает, что в случае использования XAML-разметки или процедурного кода для генерации графической визуализации, за сохранение этих визуальных элементов и обеспечение их корректной перерисовки и обновления в оптимальной манере отвечает WPF. Поэтому визуализируемые графические данные постоянно присутствуют, даже когда конечный пользователь скрывает изображение, перемещая или сворачивая окно, перекрывая одно окно другим и т.д.
В отличие от этого, прежние версии API-интерфейсов визуализации графики (включая GDI+ в Windows Forms) были графическими системами режима интерпретации (immediate-mode). Согласно этой модели на программиста возлагается ответственность за то, чтобы визуализируемые элементы корректно запоминались и обновлялись на протяжении жизни приложения. Например, в приложении Windows Forms визуализация фигуры, наподобие прямоугольника, предполагала обработку события Paint (или переопределение виртуального метода OnPain()), получение объекта Graphics для рисования прямоугольника и, что наиболее важно, добавление инфраструктуры для обеспечения сохранения изображения, когда пользователь изменяет размеры окна (например, за счет создания переменных-членов для представления позиции прямоугольника и вызова Invalidate () в программе).
Переход от графики режима интерпретации к графике сохраненного режима - однозначно хорошее решение, поскольку позволяет программистам писать и сопровождать меньший объем кода. Однако нельзя утверждать, что графический API-интерфейс WPF полностью отличается от более ранних инструментариев визуализации. Например, подобно GDI+, в WPF поддерживаются разнообразные типы объектов кистей и перьев, техника проверки попадания, области отсечения, графические трансформации и т.д.
Если есть опыт работы в GDI+ (или GDI), это значит, что уже имеется хорошее представление о том, как выполнять базовую визуализацию под WPF.
Как и с другими аспектами разработки WPF, существует выбор, каким образом выполнять графическую визуализацию, а также делать это в XAML разметке или процедурном коде С# (либо с помощью их комбинации). В частности, в WPF предлагаются три разных подхода к визуализации графических данных:
• Фигуры. В пространстве имен System.Windows.Shapes определено небольшое количество классов для визуализации двухмерных геометрических объектов (прямоугольников, эллипсов, многоугольников и т.п.). Хотя эти типы очень просты в применении и достаточно мощные, в случае непродуманного использования они могут привести к значительным накладным расходам памяти.
• Рисунки и геометрии. Второй способ визуализации графических данных предусматривает работу с наследниками абстрактного класса System.Windows.Media.Drawing. Применяя такие классы, как GeometryDrawing или ImageDrawing (в дополнение к различным геометрическим объектам), можно осуществлять визуализацию графических данных в более легковесной (но с ограниченными возможностями) манере.
• Визуальные объекты. Самый быстрый и наиболее легкий способ визуализации графических данных в WPF предполагает использование визуального уровня, который доступен только в кода С#. С помощью наследников класса System.Windows.Media.Visual можно взаимодействовать непосредственно с графической подсистемой WPF
При построении приложения велика вероятность, что придется использовать все три варианта вывода графики. В качестве эмпирического правила отметим, что если нужен небольшой объем интерактивных графических данных, которыми должен манипулировать пользователь (принимать ввод от мыши, отображать всплывающие подсказки и т.п.), то стоит отдать предпочтение классам из пространства имен System.Windows.Shapes.
В отличие от этого, рисунки и геометрии лучше подходят, когда необходимо моделировать сложные, в основном не интерактивные, основанные на векторах графические данные с использованием XAML или С#. Хотя рисунки и геометрии могут реагировать на события мыши, позволяют проверять попадание и выполнять операции перетаскивания, обычно для этого приходится писать больше кода.
Если требуется самый быстрый способ визуализации значительных объемов графических данных, то для этого наиболее подходит визуальный уровень (visual layer). Например, предположим, что WPF используется для построения научного приложения, которое должно рисовать тысячи показателей данных. За счет применения визуального уровня эти показатели можно визуализировать самым оптимальным способом. Визуальный уровень доступен только из кода С#.
Независимо от выбранного подхода (фигуры, рисунки и геометрии либо визуальные объекты), всегда будут использоваться общие графические примитивы, такие как кисти (для заполнения ограниченных областей), перья (для рисования контуров) и объекты трансформации (которые, разумеется, трансформируют данные).
Рассмотрим вывод графики с применением пространства имён System.Windows.Shapes.
Члены пространства имен System.Windows.Shapes предлагают самый прямой и интерактивный, но и наиболее ресурсоемкий по занимаемой памяти способ визуализации двумерных изображений. Это пространство имен (определенное в сборке PresentationFramework.dll), достаточно мало, и состоит всего из шести запечатанных (sealed) классов, расширяющих абстрактный базовый класс Shape: Ellipse, Rectangle, Line, Polygon, Polyline и Path.
Основные свойства:
DefiningGeometry
Возвращает объект Geometry, представляющий общие размеры текущей фигуры. Этот объект содержит только точки, используемые для визуализации данных, не имея следов функциональности UIEIement или FrameworkElement.
Fill
Позволяет указать "объект кисти" для визуализации внутренней области фигуры.
GeometryTransform
Позволяет применять трансформацию к фигуре, прежде чем она будет визуализирована на экране. Унаследованное свойство Render-Transform (из UIElement) применяет трансформацию после ее визуализации на экране.
Stretch
Описывает, как фигура располагается
внутри выделенного ей пространства,
например, внутри диспетчера компоновки.
Это управляется соответствующим
перечислением System.Windows.
Stroke, StrokeDashArray, StrokeEndLineCap, StrokeStartLineCap, StrokeThickness
Эти (и прочие) свойства, связанные со штрихами (stroke), управляют тем, как сконфигурированы линии при рисовании границ фигуры. В большинстве случаев с помощью этих свойств будет настраиваться кисть, применяемая для рисования границы или линии.
Пример применения:
Создадим WPF-приложение, которое может визуализировать фигуры на основе XAML или С#, и параллельно посмотрим, что такое процессе проверки попадания. Прежде всего, добавьте в начальную XAML-разметку элемента <Window> определение контейнера <DockPanel>, содержащего (пока пустые) элементы <Тоо1Ваг> и <Canvas> (полотно).
Каждому содержащемуся элементу назначается подходящее имя через свойство Name.
<DockPanel LastChildFill = "True">
<ToolBar DockPanel.Dock="Top" Name="mainToolBar" Height="50">
</ToolBar>
<Canvas Background="LightBlue"Name="
</DockPanel>
Теперь наполним <ToolBar> набором объектов <RadioButton>, каждый из которых содержит специфический класс-наследник Shape. При этом каждому элементу <RadioButton> назначено одно и то же групповое имя GroupName (чтобы обеспечить взаимное исключение) и соответствующее имя:
<ToolBar DockPanel.Dock="Top" Name="mainToolBar" Height="50">
<RadioButton Name="circleOption" GroupName="shapeSeleetion">
<Ellipse Fill = "Green" Height="35" Width="35" />
</RadioButton>
<RadioButtonName="rectOption" GroupName="shapeSelection">
<Rectangle Fill="Red" Height="5" Width="5" RadiusY="10" RadiusX="10" />
</RadioButton>
<RadioButton Name="lineOption" GroupName="shapeSelection">
<Line Height="35" Width="35" StrokeThickness="0" Stroke="Blue"
Xl = "0" Yl = "10" Y2 = "25" X2 = "25" StrokeStartLineCap="Triangle" StrokeEndLineCap="Round" />
</RadioButton>
</ToolBar>
Cвойство Fill позволяет указать кисть для рисования внутренностей фигуры. Когда нужна кисть сплошного цвета, можете просто задать жестко закодированную строку известных значений, а соответствующий преобразователь типов сгенерирует корректный объект.
Одна интересная характеристика типа Rectangle связана с тем, что в нем определены свойства RadiusX и RadiusY, позволяющие при желании визуализировать скругленные углы.
Линия Line представляется начальной и конечной точками с помощью свойств XI, Х2, Y1 и Y2 (учитывая, что высота и ширина применительно к линии не имеют смысла). В разметке устанавливаются несколько дополнительных свойств, управляющих визуализацией начальной и конечной точек Line, а также конфигурирующих настройки штриха.
Теперь с помощью окна Properties (Свойства) создайте обработчики события MouseLeftButtonDown для Canvas и события Click для каждой RadioButton. В файле С# цель заключается в том, чтобы визуализировать выбранную фигуру (круг, квадрат или линию), когда пользователь щелкнет на Canvas. Для начала определите следующее встроенное перечисление (и соответствующую переменную-член) внутри класса, унаследованного от Window:
public partial class MainWindow : Window
{
private enum SelectedShape
{ Circle, Rectangle, Line }
private SelectedShape currentShape;
}
Внутри каждого обработчика Click установите для переменной-члена currentShape корректное значение SelectedShape. Ниже показан код обработчика события Click объекта RadioButton по имени circleOption. Реализуйте остальные обработчики Click аналогичным образом:
private void circleOption_Click(object sender, RoutedEventArgs e)
{
currentShape = SelectedShape.Circle;
}
С помощью обработчика события MouseLeftButtonDown элемента Canvas будет визуализироваться корректная фигура (предопределенного размера) в начальной точке, соответствующей позиции X, Y курсора мыши. Ниже показана полная реализация:
private void
canvasDrawingArea_
{
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,
XI =0, X2 = 50, Yl = 0, Y2 = 50,
StrokeStartLineCap= PenLineCap.Triangle,
StrokeEndLineCap = PenLineCap.Round
};
break;
default:
return;
}
// Установить верхний левый угол для рисования на полотне.
Canvas.SetLeft(shapeToRender, e.GetPosition(
Canvas.SetTop (shapeToRender, e.GetPosition(
// Нарисовать фигуру.
canvasDrawingArea.Children.
}
В коде производится проверка переменной-члена currentShape для создания корректного объекта-наследника Shape. После этого устанавливаются значения координат левой верхней вершины внутри Canvas с использованием входного объекта MouseButtonEventArgs. И, наконец, в коллекцию объектов UIElement, поддерживаемых Canvas, добавляется новый объект-наследник Shape. Если теперь запустить программу, то можно щелкать левой кнопки мыши где угодно на Canvas и при этом на полотне будут появляться фигуры.