- PVSM.RU - https://www.pvsm.ru -
Оглавление
- Введение [1]
- Инициализация приложений Prism [2]
- Управление зависимостями между компонентами [3]
- Разработка модульных приложений [4]
- Реализация паттерна MVVM [5]
- Продвинутые сценарии MVVM [6]
- Создание пользовательского интерфейса [7]
- Навигация
- Способы коммуникации между слабосвязанными компонентами
Целью этого раздела является предоставление поверхностного руководства для XAML дизайнеров и программистов, создающих приложения с использованием WPF, Silverlight, или Windows RT и библиотеки Prism. В этом разделе описывается компоновка пользовательского интерфейса, визуальное представление, привязка данных, ресурсы и модель отображения данных. После прочтения этого раздела, вы получите поверхностное понимание того, как создавать пользовательский интерфейс с использованием библиотеки Prism, а так же, как применять техники, которые могут помочь вам создать поддерживаемый UI в модульном приложении.
Разметка составных приложений, создаваемых с помощью библиотеки Prism, построена на стандартных принципах WPF и Silverlight — разметка использует концепцию панелей, содержащих связанные элементы. Однако, в композитных приложениях, содержание панелей является динамическим и не известно до момента запуска приложения. Это заставляет дизайнеров и разработчиков создавать такую структуру разметки, которая может отображать динамическое содержимое, и затем разрабатывать каждый из элементов этого содержимого по отдельности. Для вас это значит то, что вы должны будете изучить две главные концепции библиотеки Prism: композицию контейнеров и регионы.
Композиция контейнеров является всего лишь расширением модели содержимого, предоставляемой WFP и Silverlight по умолчанию. Термин «контейнер» может обозначать любой элемент, такой как окно, страница, пользовательский элемент управления, панель, специальный элемент управления, шаблон элемента управления, или динамическое содержимое. Фиксированное содержимое будет представлять собой общую структуру элемента пользовательского интерфейса, а динамическим содержимым будет являться то, что размещается внутри регионов.
Поддержка времени проектирования со стороны инструментов, для составных приложений, несколько ограничена, но тот факт, что вы знаете, какое содержимое будет помещено в различные регионы во время выполнения, является решающим для разработки. Для примера, сравните вид окна во время проектирования на иллюстрации ниже, и вид после запуска приложения, на следующей иллюстрации. Во время проектирования, страница по большей части пустая. Сравните с видом после запуска, когда становятся видно множество элементов управления, выполняющих основные функции приложения. На основе этого вы можете представить себе сложность задачи, стоящей перед разработчиками и дизайнерами составных приложений.
Элементы не могут быть видны во время проектирования, поэтому, определение того, какого размера они должны быть, и как они будут соответствовать общему виду приложения, представляет определённые трудности. Рассмотрите следующие пункты во время создания композиции ваших контейнеров:
Expander
и ScrollViewer
для ситуаций, когда большое количество динамического содержимого должно быть размещено в ограниченном пространстве.
Главное окно Stock Trader RI в Expression Blend.
Главное окно Stock Trader RI после запуска.
Предыдущие две иллюстрации показывают одну из проблем при разработке составных приложений. Каждый элемент пользовательского интерфейса в составном приложении должен быть разработан по отдельности. Это делает затруднительной визуализацию того, как приложение будет выглядеть после запуска. Для того чтобы представить, как же будет выглядеть приложение в собранном состоянии, вы можете создать тестовый проект со страницей, или окном, содержащем все элементы пользовательского интерфейса для представления, которое вы хотите протестировать.
Рассмотрите следующие пункты при проектировании разметки составного приложения:
PositionPieChart
, расположенное на боковой панели.NewsReader
на боковой панели в Stock Trader RI. Его высота зависит от длины его титула, а ширина всегда должна соответствовать размеру региона. Те же самые правила применимы и к PositionSummaryView, где ширина таблицы должна адаптироваться к размеру экрана, а высота — к числу строк в таблице.
Рассмотрите следующие пункты, если вы используете анимации в оболочке, или в представлениях:
Expression Blend предоставляет богатый набор поведений, функций затухания, а также огромные возможности по созданию и редактированию анимации и переходов, базирующихся на состояниях и событиях. Для получения дополнительной информации, смотрите статью «VisualStateManager Class» [10] в MSDN.
Рассмотрите следующие пункты, для оптимизации производительности:
App.xaml
, или в присоединяемый словарь для предотвращения дублирования стилей.Для получения дополнительной информации, смотрите «Using Custom Fonts in Silverlight» [11].
Далее даются рекомендации и решения некоторых проблем, возникающих при визуальном проектировании приложения.
В большом решении с множеством XAML ресурсов, являющихся его частью, время загрузки визуального редактора может сильно увеличиться. Это случается из-за того, что визуальный редактор должен загрузить и разобрать все внедрённые ресурсы. Одним из методов борьбы с этим, является перенос всех XAML ресурсов в отдельный проект, компиляция этого проекта, и затем создание ссылки на полученную DLL из исходного проекта. Так как теперь все ресурсы находятся в бинарной сборке, дизайнеру не нужно самостоятельно их разбирать, что положительно влияет на производительность во время проектирования. Во время перемещения XAML ресурсов в другой проект, вы можете рассмотреть использование ComponentResourceKeys
для ваших ресурсов. Для получения подробной информации, смотрите «ComponentResourceKey Markup Extension» [12] на MSDN.
XAML является мощным и выразительным языком для создания таких ресурсов, как изображения, диаграммы, рисунки и 3D сцены. Некоторые разработчики и дизайнеры предпочитают создавать такие ресурсы вместо использования графических изображений. Первым преимуществом такого подхода, является независимость от разрешения экрана. Вторым — возможность использования только Expression Suite, как для создания всех необходимых ресурсов, так и для дизайна приложения.
Минусом использования отдельной сборки для ресурсов, является то, что редактор свойств в Expression Blend и Visual Studio 2010 не отображает ресурсы, расположенные в таких сборках. Из этого следует, что вам придётся вручную набирать имена ресурсов, расположенных в других сборках.
Составные Silverlight приложения могут быть структурированы как для уменьшения времени загрузки за счёт отложенной загрузки сборок, так и для уменьшения начального .xap файла. Одной стратегией является создание главного Silverlight приложения, а затем добавление сборок-спутников на каждый модуль. При добавлении такой сборки, вы можете выбрать один из шаблонов, это или Silverlight проект, или Silverlight библиотека классов.
Выбор для сборок-спутников шаблона Silverlight проекта, предоставляет преимущество при развёртывании: сборка будет упакована в .xap
файл при компиляции. Однако побочным эффектом является то, что визуальный дизайнер, при наличии нескольких Silverlight проектов в одном решении, использует ресурсы только из файла App.xaml
активного проекта.
Expression Blend 4 даёт решение этой проблемы. Когда он выявляет такую проблему, он показывает диалог, где предлагает выбрать необходимую библиотеку ресурсов, которая будет использоваться по всему приложению. Visual Studio 2010 не имеет такой функции, соответственно, сборки-спутники не будут иметь такой же поддержки визуального редактирования, если только вы не поместите все ресурсы уровня приложения в отдельную сборку. Если вы выбрали такой подход, то не забудьте удалить эти ресурсы из проектов сборок-спутников перед развёртыванием приложения.
Следующие пункты являются характеристиками удобных для проектирования представлений (также известных, как blendable, или tool-able):
Следующие операции выполняются множество раз за время редактирования. Пользовательский код, не являющийся дружелюбным для дизайнера, может воспрепятствовать их выполнению, уменьшая тем самым продуктивность дизайнера, или программиста.
DataContext
Для удобства использования дизайнера, Visual Studio и Expression Blend создают объекты и выполняют код во время проектирования. Однако, null reference исключения, вызванные кодом, который пытается обратиться к объектам до их создания, могут вызвать большое количество ошибок загрузки и излишних исключений во время проектирования.
Следующая таблица перечисляет основные проблемы ухудшения удобства использования дизайнеров. При избегании этих проблем и использовании техник по их устранению, вы можете значительно улучшить свою продуктивность и удовлетворённость от использования визуальных дизайнеров.
Избегайте этого в вашем коде | Visual Studio 2010 | Blend 4 |
Запуск нескольких потоков во время проектирования. К примеру, создание и старт Timer в конструкторе, или в событии Loaded . |
||
Использование элементов управления, которые могут стать причиной переполнения стека во время проектирования, или которые будут рекурсивно загружать сами себя. | ||
Генерация null reference исключения в конвертере, или в селекторе шаблона данных. | ||
Генерация null reference исключения, или любого другого исключения в конструкторе. Это может быть вызвано:
|
||
Генерация null reference исключения, или любого другого исключения внутри события Loaded элемента управления. Это может случиться, когда вы делаете предположение о состоянии элемента управления, которое может быть верно, во время выполнения, но не выполняться во время проектирования. |
||
Попытки получить доступ к объекту Application , или Application.Current во время проектирования. |
||
Использования StaticResource в WPF UserControls . |
||
Создание очень больших проектов. |
Некоторое количество практик защитного программирования могут устранить почти все пункты, перечисленные в таблице выше. Однако перед тем как взяться за проблемы в коде, исполняемом во время проектирования, мы должны понять, что элементы управления и код приложения исполняются дизайнером в изоляции, внутри неинициализированного домена приложения. Неинициализированный, в этом контексте, означает, что код загрузчика, или инициализации не выполняется.
Когда ваше приложение начинает выполняться после запуска, выполняется код в App.xaml.cs
. Если там располагается какой-либо код, от которого зависит ваше приложение, то он не будет выполнен во время проектирования. Если вы не будете ожидать, то обязательно возникнут нежелательные исключения. Для устранения этого:
null
, перед работой с объектом.Application
, или Application.Current
, проверяйте их перед этим на null
.Loaded
обращается к базе данных, или к сетевому сервису, рассмотрите следующие варианты:
DesignerProperties.GetIsInDesignMode
DesignerProperties.IsInDesignTool
Loaded
, абстрагируйте его за вызовом метода через интерфейс, после чего вы можете применить одну из множества техник использования разных реализаций во время выполнения, дизайна и тестов.
И Expression Blend, и Visual Studio используют макет корневого объекта, отображаемый в панели дизайнера. Это необходимо для предоставления дизайнером нужных функций. Так как корневой объект поддельный, его конструктор и событие Loaded
не вызываются во время проектирования. Однако оставшиеся элементы управления на сцене, конструируются нормально, и их событие Loaded
вызывается так же, как во время выполнения.
На следующей иллюстрации, конструктор корневого элемента Windows
, и его событие Loaded
не вызываются, а у дочернего элемента — вызываются.
Этот концепт является особенно важным при создании составных приложений, конструируемых динамически во время выполнения.
Большинство представлений в приложении создаются независимо. Из-за этого они обычно являются корневыми объектами в дизайнере, соответственно, их конструкторы и события Loaded
никогда не вызываются.
Однако если вы поместите такой элемент управления на поверхность проектирования как дочерний элемент, раньше изолированный, теперь он начинает выполняться во время проектирования. Если вы не следовали перечисленным выше практикам проектирования, то этот элемент может неожиданно стать источником неприятных ошибок и причиной снижения удобства использования визуального дизайнера.
Встроенные свойства времени проектирования с префиксом "d:
" дают простой способ повышения продуктивности во время проектирования.
Проблемой, которую мы пытаемся решить, является предоставление дизайнеру выражений привязки такого типа, из которого он может получить информацию о его свойствах через отражение. Также может понадобиться предоставить выборочные данные, которые будут отображаться во время проектирования.
Следующие разделы описывают, как использовать свойство d:DataContext
и расширение разметки d:DesignInstance
.
"d:
" в предыдущем параграфе является псевдонимом пространства имён, в котором располагаются средства времени проектирования. Следующие статьи более подробно раскрывают "d:
" свойства и расширения разметки:
"d:
" свойства и расширения разметки не могут быть созданы, или использованы в пользовательском коде, они могут быть применены только в XAML. Они также не компилируются в ваше приложение, они используются только инструментами в Visual Studio и Expression Blend.
d:DataContext
задаёт контекст данных времени выполнения для элемента управления и его потомков. При задании d:DataContext
вы должны всегда предоставлять данные того же типа для контекста данных DataContext
во время выполнения.
Если для элемента управления заданы и DataContext
, и a d:DataContext
, то средства дизайна выберут d:DataContext
.
Если вы не знаете, что такое расширения разметки, советую ознакомиться со статьёй в MSDN «Markup Extensions and WPF XAML» [15].
d:DesignInstance
создаёт и возвращает объект того типа, который вы хотите использовать в качестве контекста данных во время проектирования. Этот тип не обязательно должен быть с возможностью создания объекта. Следующие пункты поясняют свойства расширения d:DesignInstance
:
Свойство расширения разметки | Описание |
---|---|
Type |
Имя типа. Тип является параметром конструктора. |
IsDesignTimeCreatable |
Определяет, будет ли экземпляр этого типа создаваться. Если задано false , то будет создан псевдотип, а не реальный. Значение по умолчанию — false. |
CreateList |
Если true, то возвращает обобщённый список с элементами данного типа. Значение по умолчанию — false . |
Следующие примеры кода показывают повторяющийся шаблон для связи представлений с моделями представления.
PersonView имеет зависимость от PersonViewModel
, разрешаемую во время выполнения. Хотя модель представленная в примере является намеренно упрощённой, в реальных приложениях она будет иметь зависимости, обычно инжектируемые в конструктор.
При создании PersonView
, его зависимость PersonViewModel
будет создана и разрешена через контейнер.
Заметка.
Если модель представления не имеет каких-либо зависимостей, она может быть создана полностью в XAML. При этом установкаDataContext
иd:DataContext
не требуется.
PersonViewModel.cs
[Export]
public class PersonViewModel {
public String FirstName { get; set; }
public String LasName { get; set; }
}
PersonView.xaml.cs
[Export]
public partial class PersonView : UserControl {
public PersonView() {
InitializeComponent();
}
[Import]
public PersonViewModel ViewModel {
get { return this.DataContext as PersonViewModel; }
set { this.DataContext = value; }
}
}
Это хороший шаблон для связи представления и модели представления. Однако он оставляет представление в неведении относительно того, какой контекст данных оно должно использовать во время проектирования.
В следующем XAML вы можете увидеть расширение разметки d:DesignInstance
, используемое на элементе Grid
, которое возвращает псевдоэкземпляр PersonViewModel
, в который устанавливается свойство d:DataContext
. В результате, дочерние элементы в Grid
унаследуют значение d:DataContext
, что позволяет использовать средства проектирования для обзора свойств и типов в контексте данных, что сильно облегчает работу дизайнера и программиста.
PersonView.xaml
<UserControl
xmlns:local="clr-namespace:WpfApplication1"
x:Class="WpfApplication1.PersonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border BorderBrush="LightGray" BorderThickness="1" CornerRadius="10" Padding="10">
<Grid d:DataContext="{d:DesignInstance local:PersonViewModel}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="First Name" />
<Label Grid.Column="0" Grid.Row="1" Content="Las Name" />
<TextBox
Grid.Column="1" Grid.Row="0" Width="150" MaxLength="50"
HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Path=FirstName, Mode=TwoWay}" />
<TextBox
Grid.Column="1" Grid.Row="1" Width="150" MaxLength="50"
HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding Path=LasName, Mode=TwoWay}" />
</Grid>
</Border>
</UserControl>
Заметка: Присоединённые свойства и решение с ViewModel Locator.
Существует несколько альтернативных техник для связи представления с моделью представления, используемых в сообществе разработчиков. Существенной проблемой является то, что решение, прекрасно работающее во время выполнения, отказывается нормально работать во время проектирования. Одно из таких решений заключается в использовании присоединенного свойства и локатора моделей представлений для присвоенияDataContext
. Локатор моделей представлений необходим для того, чтобы модели представления могли быть созданы, а их зависимости разрешены.Проблемой такого решения является то, что вы должны также задавать комбинацию
d:DataContext – d:DesignInstance
, так как визуальный дизайнер не может работать с присоединёнными свойствами так же, как сd:DesignInstance
.Вне зависимости от того, какой техникой вы будете пользоваться, необходимо чтобы она использовалась согласованно во всём приложении. Согласованность упрощает развёртывание приложения и ведёт к успешному взаимодействию между дизайнером и программистом.
Команда дизайнеров WPF и Silverlight опубликовала углубленную статью, в которой описывается использование выборочных данных в WPF и Silverlight проектах. Статья доступна на MSDN: «Sample Data in the WPF and Silverlight Designer» [16].
Выборочные данные становятся особенно важными при использовании средств визуального проектирования, таких как Expression Blend, или Visual Studio. Представления могут быть наполнены данными и изображениями, что сильно упрощает работу дизайнера и делает его продуктивнее.
Пустые списки, содержащие шаблоны данных, не будут видны, пока вы не добавите в них данных. Поэтому редактирование невидимых шаблонов данных и регулярный запуск приложения, чтобы увидеть, как они будут выглядеть, сильно замедляет работу и действует на нервы дизайнерам и программистам.
Вы можете получить выборочные данных из следующих источников:
Получение данных из перечисленных источников рассматривается далее.
Expression Blend даёт возможность быстрого создания схемы XML и наполнения соответствующего XML файла данными. Это производится без добавления каких-либо посторонних проектов в решение.
Целью этого типа выборочных данных, то, что дизайнер может начать работать над проектом, не дожидаясь, когда программист напишет необходимые классы.
Хотя большая часть выборочных данных доступна как в Expression Blend, так и в Visual Studio 2010 дизайнере, выборочные XML данные являются особенностью Expression Blend и не отображаются в дизайнере Visual Studio 2010.
Заметка.
Файл выборочных XML данных не компилируется и не добавляется в сборку. Однако XML схема компилируется в итоговую сборку.
Начиная с Expression Blend 4 и Visual Studio 2010, было добавлено расширение разметки d:DesignData
, которое позволяет загружать выборочные данные во время проектирования.
XAML файл с выборочными данными содержит разметку, в которой создаётся один, или несколько экземпляров типов, после чего их свойствам назначаются некоторые данные.
У d:DesignData
есть свойство Source
, которое принимает URI на XAML файл с выборочными данными, расположенный в проекте. Расширение разметки d:DesignData
загружает этот файл, разбирает его и возвращает объектный граф. Он может быть использован свойством d:DataContext
, свойством CollectionViewSource d:DesignSource
, или свойством DomainDataSource d:DesignData
.
Одной из проблем, решаемых расширением d:DesignData
, является то, что оно может создавать выборочные данные для пользовательских типов, которые невозможно создать. Для примера, в WCF RIA приложении, объекты-сущности служб не могут быть созданы в коде. В дополнении к этому, у разработчиков могут иметься свои собственные несоздаваемые типы, для которых всё равно хотелось быть создать выборочные данные.
Вы можете менять то, как d:DesignData
обрабатывает ваши выборочные данные, посредством установки свойства Build Action у файла с данными в Solution Explorer, как показано ниже:
Когда для создания выборочных данных используется Expression Blend, он создаёт XAML файл с Build Action уже установленным в DesignData. Если вам требуются реальные типы, откройте решение в Visual Studio и измените Build Action для файла с данными на DesignDataWithDesignTimeCreatableTypes.
Заметка.
На следующей иллюстрации, свойство Custom Tool пусто. Это необходимо для корректной работы выборочных данных. По умолчанию, Expression Blend корректно оставляет это свойство пустым.Когда вы создаёте выборочные данные в Visual Studio 2010, вы обычно добавляете новую библиотеку ресурсов, после чего её редактируете. В этом случае, вы должны задать Build Action и очистить свойство Custom Tool.
Expression Blend предоставляет средства для быстрого создания и привязки выборочных XAML данных. Эти данные также могут быть использованы в дизайнере Visual Studio 2010, как показано на иллюстрации ниже.
Задание выборочных данных в Expression Blend 4
После создания выборочных данных, они появятся в панели данных, как показано ниже.
Панель данных.
После этого, вы можете перетащить их на корневой элемент представления, такой как UserControl
, что должным образом установит его d:DataContext свойство
. Вы также можете перетащить коллекцию выборочных данных на ItemsControl
, после чего Blend создаст привязку к этим данным.
Заметка.
Выборочные XAML данные не компилируются и не включаются в итоговую сборку.
Вы можете создать ресурс в XAML, где создаётся желаемый тип, после чего привязать его к DataContext
, или к списку.
Эта техника может быть использована для быстрого создания одноразовых данных, которые используются для редактирования шаблона данных.
Если вы предпочитаете создавать выборочные данные в коде, вы можете написать класс, которые имеет свойства и методы, возвращающие выборочные данные. Для примера, вы можете написать класс Customers
, который в стандартном беспараметрическом конструкторе заполняет себя экземплярами класса Customer
, заполненных требуемыми данными.
Одним из способа потребления таких данных, является использование связки d:DataContext — d:DesignInstance
, установив свойство d:DesignInstance.IsDesignTimeCreatable
в true
, для того, чтобы код был выполнен во время проектирования. Если не установить это свойство, то будет создан псевдотип, и во время проектирования будут доступны только данные о типе.
Следующий XAML демонстрирует создание экземпляра класса Customers
и установку его как d:DataContext
. Дочерние к Grid
элементы управления после этого могут использовать выборочные данные, предоставленные классом Customers
.
<Grid d:DataContext="{d:DesignInstance local:Customers, IsDesignTimeCreatable=True}">
При создании проекта составного приложения, вы должны будете принять некоторые решения относительно дизайна пользовательского интерфейса, которые будет трудно изменить в будущем. Как правило, это решения уровня всего приложения, и их согласованность увеличит продуктивность разработчиков и дизайнеров.
Эти решения следующие:
Для получения дополнительной информации о расширении Prism Library, смотрите "Extending Prism [17]."
Для получения дополнительной информации о командах, смотрите "Commands [18]" в части 5, "Implementing the MVVM Pattern [19]."
Для получения дополнительной информации о привязке данных, смотрите "Data Binding [20]" в части 5, "Implementing the MVVM Pattern [19]."
Для получения дополнительной информации о навигации регионов, смотрите часть 8, "Navigation [21]."
Для получения дополнительной информации о руководствах, обсуждаемых в этой главе, смотрите:
Автор: Unrul
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/interfejsy/33062
Ссылки в тексте:
[1] Введение: http://habrahabr.ru/post/176851/
[2] Инициализация приложений Prism: http://habrahabr.ru/post/176853/
[3] Управление зависимостями между компонентами: http://habrahabr.ru/post/176861/
[4] Разработка модульных приложений: http://habrahabr.ru/post/176863/
[5] Реализация паттерна MVVM: http://habrahabr.ru/post/176867/
[6] Продвинутые сценарии MVVM: http://habrahabr.ru/post/176869/
[7] Создание пользовательского интерфейса: http://habrahabr.ru/post/176895/
[8] Рекомендации по разработке пользовательского интерфейса: http://habrahabr.ru/post/177925/
[9] «Guidelines for Design-Time Sample Data»: http://msdn.microsoft.com/en-us/library/ff921098(v=pandp.40).aspx#GuidelinesforDesignTimeSampleData
[10] «VisualStateManager Class»: http://msdn.microsoft.com/en-us/library/cc626338(v=VS.95).aspx
[11] «Using Custom Fonts in Silverlight»: http://silverlight.net/learn/learnvideo.aspx?video=69800
[12] «ComponentResourceKey Markup Extension»: http://msdn.microsoft.com/en-us/library/ms753186.aspx
[13] «Design-Time Attributes in the WPF Designer»: http://msdn.microsoft.com/en-us/library/ee839627.aspx
[14] «Design-Time Attributes in the Silverlight Designer»: http://msdn.microsoft.com/en-us/library/ff602277(VS.95).aspx
[15] «Markup Extensions and WPF XAML»: http://msdn.microsoft.com/en-us/library/ms747254.aspx
[16] «Sample Data in the WPF and Silverlight Designer»: http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/30/sample-data-in-the-wpf-and-silverlight-designer.aspx
[17] Extending Prism: http://msdn.microsoft.com/en-us/library/gg430866(v=pandp.40).aspx
[18] Commands: http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx#Commands
[19] Implementing the MVVM Pattern: http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx
[20] Data Binding: http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx#DataBinding
[21] Navigation: http://msdn.microsoft.com/en-us/library/gg430861(v=pandp.40).aspx
[22] http://msdn.microsoft.com/en-us/library/ms752914.aspx: http://msdn.microsoft.com/en-us/library/ms752914.aspx
[23] http://msdn.microsoft.com/en-us/library/ms742521.aspx: http://msdn.microsoft.com/en-us/library/ms742521.aspx
[24] http://msdn.microsoft.com/en-us/magazine/cc163299.aspx: http://msdn.microsoft.com/en-us/magazine/cc163299.aspx
[25] http://msdn.microsoft.com/en-us/library/ms750613.aspx: http://msdn.microsoft.com/en-us/library/ms750613.aspx
[26] http://msdn.microsoft.com/en-us/library/system.windows.forms.usercontrol.aspx: http://msdn.microsoft.com/en-us/library/system.windows.forms.usercontrol.aspx
[27] http://msdn.microsoft.com/en-us/magazine/cc163421.aspx: http://msdn.microsoft.com/en-us/magazine/cc163421.aspx
[28] http://blogs.msdn.com/b/wpfsldesigner/archive/2010/01/15/learn.aspx: http://blogs.msdn.com/b/wpfsldesigner/archive/2010/01/15/learn.aspx
Нажмите здесь для печати.