Опубликован: 08.07.2011 | Уровень: для всех | Доступ: платный
Лекция 2:

Основы технологии WPF

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >

Текстовые элементы управления

В WPF определены следующие текстовые элементы управления: TextBlock, TextBox, RichTextBox и PasswordBox. Элемент PasswordBox наследуется от класса Control, а элементы TextBox и RichTextBox - от класса TextBase.

Элемент TextBlock используется для небольшого текста. Элементы управления TextBox и RichTextBox являются наследниками класса TextBase. Элемент TextBox всегда хранит строку текста. Элемент RichTextBox может хранить содержимое FlowDocument, которое может содержать в себе сложную комбинацию элементов. Элемент управления PasswordBox содержит строку текста, используя элемент SecureString для защиты от некоторых видов атак.

Элемент управления TextBox, как правило хранит одну строку текста:

<TextBox Name="txtA">Выбор текста</TextBox>

Если необходимо создать многострочное представление, то свойству TextWrapping необходимо присвоить значение Wrap. Для многострочного элемента TextBox можно задать минимальное и максимальное количество строк, используя свойства MinLines и MaxLines.

Элементы управления списками

Элементы управления ListBox и ComboBox являются элементами управления списками. Эти элементы управления являются потомками класса ItemsControl через класс Selector.

Класс ItemsControl является базовым для всех элементов управления списками и предусматривает два способа заполнения списка элементов. В первом способе осуществляется добавление элемента прямо в коллекцию Items, при котором используется код или XAML. Во втором способе осуществляется привязка данных через задание свойства ItemsSource – источника данных (коллекции элементов). Класс Selector имеет свойства, позволяющие отслеживать выделенный в данный момент времени элемент ( SelectedItem ) списка или его позицию ( SelectedIndex ).

Для добавления элементов в ListBox можно вложить элементы ListBoxItem в элемент управления ListBox, как это показано для составления списка цветов (зеленый, голубой, желтый, красный):

<ListBox>
   <ListBoxItem>Зеленый</ListBoxItem>
    <ListBoxItem>Голубой</ListBoxItem>
    <ListBoxItem>Желтый</ListBoxItem>
   <ListBoxItem>Красный</ListBoxItem>
</ListBox>

Элемент управления ListBox хранит каждый вложенный объект в своей коллекции. При этом ListBoxItem может хранить не только строки, но и любой произвольный элемент.

Элемент управления ComboBox подобен ListBox, но для визуализации использует выпадающий список и пользователь может выбрать только один элемент из списка.

Специализированные элементы управления

В WPF имеются элементы управления, использующие диапазоны значений: ScrollBar, ProgressBar и Slider. Данные элементы управления являются наследниками класса RangeBase, в котором определены такие свойства как Value – текущее значение элемента управления, Minimum и Maximum – минимальное и максимальное допустимые значения.

ScrollBar – элемент управления, предоставляющий полосу прокрутки с перемещаемым элементом, позиция которого соответствует определенному значению.

Элемент управления ProgressBar показывает ход выполнения длительной задачи.

Элемент управления Slider используется для задания числового значения путем перемещения бегунка на линейке прокрутки.

Команды

Командная модель WPF предоставляет следующие возможности:

  • делегирование событий подходящим командам;
  • поддержание включенного состояния элемента управления в синхронизированном виде с помощью состояния соответствующей команды.

Модель команд включает следующие компоненты:

  • команды, которые представляют задачу приложения, с механизмом слежения за их доступностью при выполнении программы;
  • привязка команд, которая подразумевает соединение команды с логикой приложения, отвечающей за обслуживание определенной области пользовательского интерфейса;
  • источник команды, которые её инициирует;
  • целевые объекты команды – элементы приложения, для которых предназначена данная команда.

Классы команд WPF должны поддерживать интерфейс ICommand.

public interface ICommand
    {
        void Execute(object par);
        bool CanExecute(object par);
        event EventHandler CanExecuteChanged;
    }

Метод Execute() определяет реализацию команды в приложении. Это может быть код логики приложения или возбуждение события, обрабатываемого в другом классе приложения. Метод CanExecute() возвращает информацию о состоянии доступности команды. Методы Execute() и CanExecute() могут вызываться с параметром par, который используется для передачи дополнительной информации. Событие CanExecuteChanged вызывается при изменении состояния доступности команды. По этому событию вызывается метод CanExecute() и проверяется состояние команды.

В WPF существует библиотека базовых команд, которые доступны через статические свойства следующих статических классов:

  • ApplicationCommands – представлены общие команды, такие как Создать, Открыть, Копировать, Сохранить и др. ;
  • Navigation Commands – представлены команды для навигации;
  • Editing Commands – включает команды для редактирования документов;
  • Media Commands – объединяет команды для работы с мультимедиа.

Для инициализации команды необходимо использовать источник команды, а для ответа на нее – привязку команды с переадресацией её выполнения обычному обработчику события.

Предположим, что источником команды Создать является кнопка New. С помощью свойства Command связываем кнопку с командой New.

<Button Name="New" Content="Создать" Width="200" Command="New"/>

Следующим шагом необходимо создать привязку команды к окну Window.

<Window.CommandBindings>
	<CommandBinding Command="New" 
		Executed="CommandBinding_Executed" 
		CanExecute="CommandBinding_CanExecute"/>
</Window.CommandBindings>

В привязке для объекта CommandBinding кроме команды New необходимо указать обработчики для методов Execute() и CanExecute() через соответствующие свойства Executed и CanExecute. Обработчик CommandBinding_Executed будет реализовывать бизнес-логику команды Создать, обработчик CommandBinding_CanExecute – проверять доступность команды.

При создании пользовательской команды целесообразно использовать класс RoutedCommand, который реализует интерфейс ICommand.

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

public class DataCommands
{
     private static RoutedCommand edit;
     public static RoutedCommand Edit
    {
        get { return DataCommands.edit; }
    }
    static DataCommands()
    {
        InputGestureCollection inputs = new InputGestureCollection();
        inputs.Add(new KeyGesture(Key.E, ModifierKeys.Control, "Ctrl+E"));
        Edit = new RoutedCommand("edit", typeof(DataCommands), inputs);
    }
}

В классе DataCommands объявлены статические поле ( edit ) и свойство ( Edit ) экземпляра класса RoutedCommand. Статический конструктор создает экземпляр команды Создать ( Edit ), используя экземпляр ( inputs )) класса InputGestureCollection. Класс InputGestureCollection представляет упорядоченную коллекцию объектов KeyGesture, которые определяют "горячую" клавишу для вызова команды. В приведенном примере это комбинация клавиш "Ctrl+E". Далее необходимо установить для команды источник и привязать команду, как это было рассмотрено для команды из библиотеки .NET.

< Лекция 1 || Лекция 2: 123456 || Лекция 3 >
Александр Петров
Александр Петров

При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. 
Вопрос, как отследить и отключить добавление элемента в Items?

Максим Спиридонов
Максим Спиридонов

В пятой лекции на второй странице в компиляторе выскакивает ошибка в строчке :

ObjectQuery<Employee> employees = DataEntitiesEmployee.Employees;

Ошибка CS0029

Не удается неявно преобразовать тип "System.Data.Entity.DbSet<WpfApplProject.Employee>" в "System.Data.Entity.Core.Objects.ObjectQuery<WpfApplProject.Employee>".

в using прописал все как положено, здесь похоже именно с преобразованием типов проблемы

Igor Chelyadinski
Igor Chelyadinski
Беларусь, Минск, №54, 2013
Валентина Алешина
Валентина Алешина
Россия