При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. |
Разработка многофункциональных бизнес-приложений
Если в источнике данных указаны несколько объектов FilterDescriptor, то они могут работать по схеме "Или" ( Or ) и по схеме "И" ( And ). Режим объединения фильтров задается свойством FilterOperator источника данных и в проектируемом приложении ему задано значение Or.
На рис. 10.30 иллюстрируется функциональность элемента управления AutoCompleteBox по формированию подсказки при вводе символов, а на рис. 10.31 – результаты работы приложения при выполнении фильтрации по должности.
Следующим этапом проектирования приложения является реализация функция редактирования, добавления и удаления данных по сотрудникам организации.
На странице EmployeePage создадим кнопки buttonNewEmployee, buttonEdit и buttonDelete для реализации выполнения соответствующих операций.
Добавим в клиентскую часть приложения дочернее окно, с помощью которого будем редактировать и добавлять данные по сотрудникам. Для этого в помощнике Добавление нового элемента необходимо выбрать шаблон Дочернее окно Silverlight (1 – рис. 10.32) и задать имя EmployeeChildWindow (2 – рис. 10.32).
В конструкторе окна EmployeeChildWindow откроем вкладку Источники данных и для сущности Employee сервиса данных EmployeeDomainContext зададим формат представления в виде Таблицы ( рис. 10.33). Для атрибутов сущности Employee зададим форматы в соответствии с форматами, представленными на рис. 10.33
С помощью мыши перетащим сущность Employee из вкладки Источники данных в конструктор окна EmployeeChildWindow. В результате будут сформированы элементы управления для работы со свойствами сущности Employee ( рис. 10.34).
В 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).
Текстовые поля редактируются непосредственно в поле, должность выбирается из выпадающего списка, даты задаются с помощью выпадающего календаря, а при наведении курсора на фотографию выводится подсказка "Для изменения фотографии щелкните на ней правой кнопкой мыши" и для корректировки фотографии по нажатию правой кнопки мыши выводится окно "Открыть" для задания нового файла фотографии. Для завершения редактирования нажимается кнопка ОК, а для отмены редактирования – кнопка Отмена.