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

Разработка многофункциональных бизнес-приложений

Если в источнике данных указаны несколько объектов FilterDescriptor, то они могут работать по схеме "Или" ( Or ) и по схеме "И" ( And ). Режим объединения фильтров задается свойством FilterOperator источника данных и в проектируемом приложении ему задано значение Or.

На рис. 10.30 иллюстрируется функциональность элемента управления AutoCompleteBox по формированию подсказки при вводе символов, а на рис. 10.31 – результаты работы приложения при выполнении фильтрации по должности.

Подсказка при вводе должности

увеличить изображение
Рис. 10.30. Подсказка при вводе должности
Результаты фильтрации по должности

увеличить изображение
Рис. 10.31. Результаты фильтрации по должности

Следующим этапом проектирования приложения является реализация функция редактирования, добавления и удаления данных по сотрудникам организации.

На странице EmployeePage создадим кнопки buttonNewEmployee, buttonEdit и buttonDelete для реализации выполнения соответствующих операций.

Добавим в клиентскую часть приложения дочернее окно, с помощью которого будем редактировать и добавлять данные по сотрудникам. Для этого в помощнике Добавление нового элемента необходимо выбрать шаблон Дочернее окно Silverlight (1 – рис. 10.32) и задать имя EmployeeChildWindow (2 – рис. 10.32).

Создание дочернего окна

увеличить изображение
Рис. 10.32. Создание дочернего окна

В конструкторе окна EmployeeChildWindow откроем вкладку Источники данных и для сущности Employee сервиса данных EmployeeDomainContext зададим формат представления в виде Таблицы ( рис. 10.33). Для атрибутов сущности Employee зададим форматы в соответствии с форматами, представленными на рис. 10.33

Источники данных

Рис. 10.33. Источники данных

С помощью мыши перетащим сущность Employee из вкладки Источники данных в конструктор окна EmployeeChildWindow. В результате будут сформированы элементы управления для работы со свойствами сущности Employee ( рис. 10.34).

Дочернее окно EmployeeChildWindow

Рис. 10.34. Дочернее окно EmployeeChildWindow

В XAML-описание окна будет добавлен контекст данных для сущности Employee.

<riaControls:DomainDataSource AutoLoad="True" 
	d:DesignData="{d:DesignInstance my1:Employee, CreateList=true}" 
	Name="employeeDomainDataSource" Height="0" Width="0"
	LoadedData="employeeDomainDataSource_LoadedData" 
	QueryName="GetEmployeesQuery">
	<riaControls:DomainDataSource.DomainContext>
		<my:EmployeeDomainContext />
	</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>

Если проанализировать XAML-описание окна EmployeeChildWindow, то можно увидеть, что элемент Image для отображение фотографии требует корректировки, а элемент ComboBox не настроен правильно на источник данных. Для отображения фотографии в привязке необходимо использовать конвертор. В дополнение к этому поместим объект Image в рамку Border.

<Border Grid.Column="2" Name="Border"
	Padding="5" Width="200" Height="250" CornerRadius="10" 
	Background="#FFC8E5E9" Margin="3" VerticalAlignment="Center"
	ToolTipService.ToolTip=
	"Для изменения фотографии щелкните на ней правой кнопкой мыши" 
	MouseRightButtonDown="Border_MouseRightButtonDown" >
	<Image  Height="240" HorizontalAlignment="Center" Margin="3" 
		Name="pictureImage" 
		Source="{Binding Path=Picture, Converter={StaticResource ImageConverter}}" 
			Stretch="UniformToFill" VerticalAlignment="Center" Width="196" />
</Border>

Для подготовки источника данных для comboBoxTitle необходимо в XAML-описание окна EmployeeChildWindow добавить контекст данных для сущности Title.

<riaControls:DomainDataSource AutoLoad="True" 
	d:DesignData="{d:DesignInstance my1:Title, CreateList=true}" 
	LoadedData="titleDomainDataSource_LoadedData" 
	Name="titleDomainDataSource" 
	QueryName="GetTitlesQuery">
	<riaControls:DomainDataSource.DomainContext>
		<my:EmployeeDomainContext />
	</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>

После этого можно отредактировать описание для выпадающего списка должностей.

<ComboBox x:Name="comboBoxTitle" Height="23" Grid.Column="2" Grid.Row="4" 
	HorizontalAlignment="Left" 
	ItemsSource="{Binding ElementName=titleDomainDataSource, Path=Data}"
	DisplayMemberPath="Title1" 
	SelectedValuePath="ID" 
	SelectedValue="{Binding Path=TitleID,  Mode=TwoWay,
				  UpdateSourceTrigger=Default}"  
	Margin="3,3,0,0" VerticalAlignment="Top" Width="198">
</ComboBox>

Теперь следует создать вызов дочернего окна из страницы EmployeePage при нажатии кнопки buttonEdit.

private void buttonEdit_Click(object sender, RoutedEventArgs e)
{
	Employee employeeEdit = employeeDataGrid.SelectedItem as Employee;
	if (employeeEdit != null)
	{
	EmployeeChildWindow winEmpEdit = new EmployeeChildWindow(employeeEdit);
	winEmpEdit.Closed += new EventHandler(winEmpEdit_Closed);
	winEmpEdit.Title = "Редактирование данных";
	winEmpEdit.Show();
	}
}

В обработчике нажатия кнопки buttonEdit создается экземпляр employeeEdit сущности Employee на основе выделенной в текущий момент строки сетки данных employeeDataGrid.

Employee employeeEdit = employeeDataGrid.SelectedItem as Employee;

Если объект employeeEdit существует, то создается экземпляр winEmpEdit дочернего окна EmployeeChildWindow, которому в качестве параметра передается экземпляр сущности данных employeeEdit.

EmployeeChildWindow winEmpEdit = new EmployeeChildWindow(employeeEdit);

Затем включают прослушивания события закрытия окна.

winEmpEdit.Closed += new EventHandler(winEmpEdit_Closed);

Для дочернего формируется заголовок и окно выводится на экран дисплея.

winEmpEdit.Title = "Редактирование данных";
winEmpEdit.Show();

Обработка события закрытия дочернего окра реализуется методом winEmpEdit_Closed(), в котором по результату нажатия кнопки ОК проводят сохранение изменений в базе данных

employeeDomainDataSource.SubmitChanges();

а при нажатии кнопки Отмена – отмена проведенного редактирования данных

employeeDomainDataSource.RejectChanges();

Полный код обработчика winEmpEdit_Closed приводится ниже.

void winEmpEdit_Closed(object sender, EventArgs e)
{
    EmployeeChildWindow emp = (EmployeeChildWindow)sender;
    if (emp.Employee != null)
    {
        if (emp.DialogResult == true)
        {
            employeeDomainDataSource.SubmitChanges();
        }
        else
        {
            employeeDomainDataSource.RejectChanges();
        }
    }
}

При редактировании данных о сотрудниках организации необходимо в списке сотрудников выделить строку с данными по сотруднику, которые подлежат редактированию, нажать кнопку Редактирование для открытия Окна редактирования ( рис. 10.35).

Редактирование данных

увеличить изображение
Рис. 10.35. Редактирование данных

Текстовые поля редактируются непосредственно в поле, должность выбирается из выпадающего списка, даты задаются с помощью выпадающего календаря, а при наведении курсора на фотографию выводится подсказка "Для изменения фотографии щелкните на ней правой кнопкой мыши" и для корректировки фотографии по нажатию правой кнопки мыши выводится окно "Открыть" для задания нового файла фотографии. Для завершения редактирования нажимается кнопка ОК, а для отмены редактирования – кнопка Отмена.

Александр Петров
Александр Петров

При загрузке данных из БД возникает исключение 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
Валентина Алешина
Валентина Алешина
Россия