Главная » WPF » Пользовательские элементы управления примеры использования

0

В предыдущем  разделе  мы узнали,  как создавать  окна. Интересно отметить, что окно  – это способ  инкапсуляции определенной  функциональности. Кроме того, окна изолированы, потому  что, во#первых, для  них определен  новый  тип

CLR,  а, во#вторых, потому  что окна  верхнего  уровня  изолированы визуально. Часто возникает  желание разбить описание  пользовательского интерфейса на мелкие  инкапсулированные части, которые не обязательно представляют собой отдельные окна. Здесь#то и пригодятся пользовательские элементы  управления.

Рис. 2.13. Вывод списка открытых окон

Есть две категории разработчиков элементов управления. Одни создают поль# зовательские элементы  (user  control), другие – нестандартные (custom  control). Названия не очень осмысленные  (восходят  к временам Visual Basic 5.0, в котором появился простой  способ разрабатывать элементы  управления), но относятся  к двум совершенно  разным ситуациям.  Я предпочитаю  такое определение: пользо# вательские  элементы – это способ инкапсуляции частей графического  интерфей# са, а нестандартные – это повторно используемые элементы, которые можно при# менять и в других приложениях. Вопрос о том, где проходит граница между ни# ми, – источник ожесточенных споров.

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

<ContentControl …

x:Class=’EssentialWPF.MyUserControl’

<Button Click=’ButtonClicked’>Hello World</Button>

</ContentControl>

Как и в случае окон, всю логику можно поместить в файл с кодом:

public partial class MyUserControl : ContentControl {

public MyUserControl() {

InitializeComponent();

}

void ButtonClicked(object sender, RoutedEventArgs e) { MessageBox.Show(«Howdy!»);

}

}

Этот новый элемент можно использовать в любом месте приложения, но сна# чала мы должны  создать для него пространство  имен XML. Язык XAML позво# ляет ассоциировать любое пространство  имен CLR с пространством имен XML:

<Window … x:Class=’EssentialWPF.UserControlHost’

xmlns:l=’clr namespace:EssentialWPF’ Title=’User Controls’

</Window>

Voilа! Теперь этот пользовательский элемент управления можно поместить в окно (рис. 2.14):

<Window … x:Class=’EssentialWPF.UserControlHost’ xmlns:l=’clr namespace:EssentialWPF’ Title=’User Controls’

<StackPanel>

<l:MyUserControl />

<l:MyUserControl />

</StackPanel>

</Window>

Рис. 2.14. Окно с двумя экземплярами нового пользовательского элемента управления

Ссылается

 

Рис. 2.15. Логическая модель работы ссылок на пользовательский элемент управления

Здесь два нестандартных тега <l:MyUserControl /> ссылаются  на компонент, определенный в файле MyUserControl.xaml (рис. 2.15). Если изменить  его опре# деление, то изменятся оба элемента.

Назначение пользовательских элементов – разбить приложение на компонен# ты. Если же нужно создать совсем новый элемент  (с поддержкой  тем и т.д.), то стоит подумать о нестандартных элементах. Для создания  таких элементов  нуж# но хорошо понимать  модель элементов  управления в WPF,  а это уже выходит за рамки настоящей  книги.

Итак,  мы видели,  что создание  окна  – частный  случай  создания  пользова# тельского элемента управления. Еще один способ разбить приложение на обозри# мые и удобные для сопровождения части – воспользоваться страницами,  кото# рые являются частью инфраструктуры навигации в WPF.

Навигация и страницы

Часто языку HTML приписывают появление навигации в приложениях, но на самом деле она гораздо старше. Любой мастер, программа  gopher или электрон# ная доска объявлений – вот ранние примеры навигации.

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

Чтобы было проще создавать приложения с такой моделью навигации,  в WPF

встроен   готовый   каркас.   Его  основные   компоненты:   навигационный  узел

(NavigationWindow), содержимое (Page) и журнал (рис. 2.16)15. Задача журнала – вести учет действий, имеющих отношений  к навигации,  но в каркасе ему не соот# ветствует  никакой  открытый  класс.  NavigationWindow – это принимаемый по умолчанию  навигационный узел  в WPF. Этот  класс  является производным от Window и добавляет  стандартный интерфейс навигации (кнопку Назад и т.д.), а также необходимую для навигации инфраструктуру. Класс NavigationWindow имеет доступ к тем же самым средствам уровня приложения, что и Window.  С его помощью мы можем реализовать навигацию в однодокументной оконной модели.

В WPF целью  навигации может  быть  любое  содержимое:  объекты  данных, примитивные типы (например, строки)  или страницы. Page – не более чем удоб# ный класс, содержащий  вспомогательные методы, облегчающие навигацию.

Прежде чем переходить  к полноценному решению на базе разметки,  рассмотрим простой пример навигации,  реализованный целиком программно, чтобы понять, как стыкуются  все компоненты.  Для начала создадим новое окно. Поскольку мы хотим поддержать навигацию, унаследуем класс окна от NavigationWindow, а не от Window:

Рис. 2.18. После перехода на вторую страницу

Все это возможно  благодаря  журналу.  Объект  NavigationWindow  предостав# ляет стандартный интерфейс для навигации (кнопку Назад, полосу заголовка  и т.д.) и автоматически создает журнал.

Эквивалентная этому примеру  разметка  по идее должна выглядеть  как хоро# шо знакомый  HTML#код. Мы можем воспользоваться тем фактом, что класс Hyperlink уже поддерживает навигацию  на основе URI.  Это позволит  заменить весь написанный выше код следующей разметкой:

<!— page1.xaml —>

<Page …

WindowTitle=’Page 1’>

<TextBlock>

<Hyperlink NavigateUri=’page2.xaml’> Click for page 2

</Hyperlink>

</TextBlock>

</Page>

<!— page2.xaml —>

<Page …

WindowTitle=’Page 2’>

</Page>

<!— navexample.xaml —>

<NavigationWindow … x:Class=’EssentialWPF.NavExample’ Source=’page1.xaml’>

</NavigationWindow>

Свойству  Source объекта NavigationWindow можно присвоить  URI#имя  пер# вой страницы  Page1.xaml, чтобы обойтись без создания  экземпляра типа. Анало# гично если свойству  NavigateUri объекта  Hyperlink присвоить  URI#имя  второй страницы  Page2.xaml, то не придется  писать код обработки события Click.

Если, как часто бывает, мы не хотим менять стандартный вид окна навигации, то можно не определять его вовсе. Присвоив значение свойству StartupUri объек# та Application,  мы сможем сразу запустить  страницу:

<!— app.xaml —>

<Application … x:Class=’EssentialWPF.App’ StartupUri=’page1.xaml’>

</Application>

 

Источник: К. Андерсон  Основы  Windows Presentation Foundation. Пер. с англ. А. Слинкина — М.: ДМК Пресс, 2008 — 432 с.: ил.

По теме:

  • Комментарии