Создание панели инструментов

94

Щелкните на вкладке Documents API непосредственно на монтажном столе, чтобы активизировать ее для последующей правки (напомним, что это вторая вкладка в элементе управления типа TabItem). У вас уже должен быть диспетчер компоновки типа Grid, используемый по умолчанию в качестве прямого потомка элемента управления типа TabItem, но вы должны заменить его объектом типа StackPanel, перейдя к панели Objects and Timeline, щелкнув правой кнопкой мыши на заменяемом диспетчере компоновки и выбрав команду Change Layout Type из всплывающего контекстного меню.

Первым элементом управления, размещаемым на блочной панели типа StackPanel должна стать специальная панель инструментов с двумя кнопками. Поэтому найдите элемент управления типа ToolBar в библиотеке ресурсов и добавьте его экземпляр в выбранный объект типа StackPanel. Доступный на платформе WPF элемент управления типа ToolBar может быть настроен таким образом, чтобы содержать любое количество элементов управления. Когда же потребуется добавить в него элемент средствами Expression Blend IDE, найдите его свойство Items (Элементы) и щелкните на кнопке с меткой ...:

Заполнение панели инструментов ToolBar

Щелкните на кнопке Add another item (Добавить еще один элемент), расположенной в нижней части открывшегося диалогового окна, чтобы открыть другое диалоговое окно и найти в нем нужный элемент по имени. А справа от этой кнопки раскрывается список, из которого можно выбрать наиболее часто применяемые элементы управления:

Добавление элементов в коллекцию Items

Введите в открывшемся окне редактора коллекций два объекта типа Button. Сделав это, вы сразу же заметите, что каждый элемент может быть выбран и отредактирован в данном редакторе:

Редактирование объектов из коллекции Items

Настройте свойства каждого объекта типа Button по своему усмотрению, но для рассматриваемого здесь примера в их свойствах Content должны быть установлены такие же значения, как и в приведенных ниже строках разметки XAML:

<Button BorderBrush="#0035F70E" Content="Save Doc"/>
<Button BorderBrush="#0043F513" Content="Load Doc"/>

Вернитесь к визуальному конструктору, откройте библиотеку ресурсов и найдите элемент управления типа FlowDocumentReader. Разместите его на блочной панели типа StackPanel, присвойте ему имя myDocumentReader и растяните по всей поверхности блочной панели типа StackPanel. На данном этапе компоновка второй вкладки должна выглядеть так:

Компоновка вкладки Documents API

Выберите элемент управления типа FlowDocumentReader на панели Objects and Timeline и перейдите к области Miscellaneous (Разное) на панели Properties. Щелкните на кнопке New рядом со свойством Document. В итоге разметка XAML обновится, и в ней появится пустой элемент <FlowDocument>:

<FlowDocumentReader Height="389.723" FontSize="16">
						<FlowDocument/>
					</FlowDocumentReader>

В этом элементе можно теперь ввести классы форматирования документа, в том числе List, Paragraph, Section, Table, LineBreak, Figure, Floater и Span. Именно этим вам и придется заняться далее.

Как только вы введете новый документ в рассматриваемый здесь контейнер документов, его свойство Document станет расширяемым, выявив массу новых свойств, предназначенных для оформления текстового документа. В данном примере наибольший интерес представляет свойство Blocks (Collection):

Заполнение элемента типа FlowDocument

Щелкните сначала на кнопке с меткой ... справа от данного свойства, а затем на кнопке Add another item в открывшемся диалоговом окне. Выберите классы блоков документа List, Paragraph и Section, чтобы ввести их в текущий контейнер:

Добавление документов в блок

Каждый из блоков документа может быть отредактирован в редакторе блоков. Кроме того, каждый блок может содержать связанные с ним субблоки. Так, если выбрать блок типа Section, обозначающий раздел документа, то его можно дополнить субблоком типа Paragraph, представляющим абзац.

Настройте блок типа Section по своему усмотрению, но оставьте блок типа List и исходный блок типа Paragraph пустыми, поскольку манипулировать ими предстоит посредством кода. Ниже приведен один из возможных вариантов настройки элемента типа FlowDocument в диспетчере компоновки типа FlowDocumentReader:

<FlowDocumentReader Height="389.723" FontSize="16">
						<FlowDocument>
							<Section Background="Black" Foreground="#FFF0F117">
								<Paragraph FontSize="20">
									Этот элемент использует WPF Document API!
								</Paragraph>
							</Section>
							<List/>
							<Paragraph/>
						</FlowDocument>
					</FlowDocumentReader>

Если вы запустите теперь свое приложение на выполнение, нажав функциональную клавишу <F5>, то должны уже иметь возможность изменять масштаб документа ползунковым регулятором в правом нижнем углу главного окна, производить поиск по ключевому слову, указываемому в поле Search слева внизу, а также отображать текстовые данные одним из трех способов с помощью соответствующих кнопок компоновки.

Прежде чем перейти к следующему этапу работы над текущим проектом, попробуйте отредактировать разметку XAML, чтобы воспользоваться другим контейнером для элемента типа FlowDocument, например FlowDocumentScrollViewer или RichTextBox, вместо диспетчера компоновки типа FlowDocumentReader. Сделав это, еще раз запустите приложение на выполнение и обратите внимание на другие способы и средства обработки текстовых данных в документе. После этого вернитесь к диспетчеру компоновки типа FlowDocumentReader.

Это руководство посвящено главным образом инструментальным средствам разработки приложений в среде Expression Blend IDE, тем не менее вы должны знать, что элементами документа можно манипулировать и непосредственно в коде. В качестве упражнения вам предстоит построить в коде блок типа List и оставшийся блок типа Paragraph.

Возможность манипулировать документами непосредственно в коде имеет, безусловно, большое значение, поскольку заполнять элемент типа FlowDocument придется с учетом информации, полученной от пользователя, из базы данных, внешних файлов и прочих ресурсов. Но прежде чем сделать это, следует воспользоваться встроенным в Expression Blend редактором XAML, чтобы присвоить блокам типа List и Paragraph подходящие имена для удобного обращения к ним в исходном коде, как показано ниже:

<List x:Name="listOfFunFacts"/>
<Paragraph х:Name="paraBodyText"/>

Итак, определите новый метод PopulateDocument() в файле исходного кода своего проекта. Сначала в этом методе в блок типа List будет добавлен ряд новых элементов списка, представленных объектами типа ListItems, причем каждый из них будет состоять из блока типа Paragraph с одним объектом типа Run. Затем в этом вспомогательном методе с помощью трех отдельных объектов типа Run будет динамически отформатирован абзац. Ниже приведен исходный код данного метода:

private void PopulateDocument()
		{
			// Ввести данные в элемент списка
			this.listOfFunFacts.FontSize = 14;
			this.listOfFunFacts.ListItems.Add(new ListItem(new Paragraph
				(new Run("Фиксированный документ"))));
			this.listOfFunFacts.ListItems.Add(new ListItem(new Paragraph
				(new Run("Элемент списка"))));
			this.listOfFunFacts.ListItems.Add(new ListItem(new Paragraph
				(new Run("Block UI Container"))));
			this.listOfFunFacts.ListItems.Add(new ListItem(new Paragraph
				(new Run("As runtime!"))));
			
			// Вводим данные в параграф
			Run prefix = new Run("Генерируем данный параграф");
			Bold b = new Bold();
			Run ifix = new Run(" dynamically ");
			ifix.Foreground = Brushes.Red;
			ifix.FontSize = 30;
			b.Inlines.Add(ifix);
			
			Run suffix = new Run(" at runtime!");
			this.paraBodyText.Inlines.Add(prefix);
			this.paraBodyText.Inlines.Add(ifix);
			this.paraBodyText.Inlines.Add(suffix);
		}

Вызовите данный метод из конструктора главного окна приложения, как показано ниже:

public MainWindow()
		{
			this.InitializeComponent();
			PopulateDocument();

			// Insert code required on object creation below this point.
		}

Введя приведенный выше исходный код, запустите приложение на выполнение и посмотрите, как новое содержимое документа формируется динамически.

А теперь нужно разобраться с функциями двух кнопок, введенных на панели инструментов, созданной на вкладке Documents API. С этой целью воспользуйтесь панелью Properties, чтобы организовать обработку события Click, наступающего после щелчка на каждой из кнопок, представленных объектами типа Button, указав для каждой из них разные имена метода обработки данного события. Затем импортируйте в файл исходного кода главного окна приложения (объекта типа Window) указанные ниже два пространства имен NET. предоставляющих доступ к объектам ввода-вывода файлов, а также к объектам типа XamlReader и XamlWriter, которые потребуются для сохранения и загрузки данных документа:

using System.IO;
using System.Windows.Markup;

Для сохранения данных документа остается лишь создать XAML-файл, в котором будет храниться содержимое документа. А разметка, описывающая сами данные, предоставляется в свойстве Document диспетчера компоновки типа FlowDocumentReader, как показано в приведенном ниже исходном коде метода обработки событий:

// Сохранение документа
		private void ButtonSave_Click(object sender, System.Windows.RoutedEventArgs e)
		{
			using(FileStream fs = File.Open("documentData.xaml",FileMode.Create))
			{
				XamlWriter.Save(this.myDoc.Document, fs);
			}
		}
		
		// Загрузка документа
		private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
		{
			using(FileStream fs = File.Open("documentData.xaml",FileMode.Create))
			{
				FlowDocument doc = XamlReader.Load(fs) as FlowDocument;
				this.myDoc.Document = doc;
			}
		}
Потоковый документ
Пройди тесты
Лучший чат для C# программистов