пятница, 27 августа 2010 г.

Форма в виде всплывающего окошка в Silverlight 4. Часть 8

Теперь сделаем нашу форму с данными в виде всплывающего окошка, это достаточно стандартный сценарий.

Для этого во Views я добавлю новый элемент Silverlight Child Window, на страницу положу DataForm.

<controls:ChildWindow x:Class="BusinessApplication1.Views.CustomerView"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"

xmlns:dataControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"

Width="400" Height="300"

Title="Customer View">

<StackPanel>

<dataControls:DataForm

AutoGenerateFields="True"

AutoCommit="False"

AutoEdit="False"

Width="350"

EditEnded="DataForm_EditEnded"

AutoGeneratingField="DataForm_AutoGeneratingField"

Name="customerDataForm"

>

</dataControls:DataForm>

</StackPanel>

</controls:ChildWindow>

И добавим все необходимые обработчики в код cs файла.

Также нам понадобятся переменные для хранения текущего отображаемого элемента и для доменного источника данных.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using BusinessApplication.BLL;

using System.Windows.Data;

using System.ServiceModel.DomainServices.Client;

using BusinessApplication1.Web.Services;

namespace BusinessApplication1.Views

{

public partial class CustomerView : ChildWindow

{

Customer currentItem;

DomainDataSource customerDomainDataSource;

public CustomerView(Customer currentItem, DomainDataSource customerDomainDataSource)

{

InitializeComponent();

this.currentItem = currentItem;

this.customerDomainDataSource = customerDomainDataSource;

customerDataForm.CurrentItem = currentItem;

}

private void OKButton_Click(object sender, RoutedEventArgs e)

{

this.DialogResult = true;

}

private void CancelButton_Click(object sender, RoutedEventArgs e)

{

this.DialogResult = false;

}

private void DataForm_EditEnded(object sender, DataFormEditEndedEventArgs e)

{

if (e.EditAction == DataFormEditAction.Commit)

{

customerDomainDataSource.SubmitChanges();

}

}

private void DataForm_AutoGeneratingField(object sender, DataFormAutoGeneratingFieldEventArgs e)

{

if (e.PropertyName == "Town")

{

var ctx = (customerDomainDataSource.DomainContext as DomainService1);

var townsQ = ctx.Load(ctx.GetTownsQuery(), OnGetTowns, e.Field);

}

}

public void OnGetTowns(LoadOperation loadOperation)

{

Binding binding = new Binding("Town");

binding.Mode = BindingMode.TwoWay;

var townCombobox = new ComboBox();

townCombobox.ItemsSource = loadOperation.Entities;

townCombobox.DisplayMemberPath = "Name";

townCombobox.SetBinding(ComboBox.SelectedItemProperty, binding);

var item = loadOperation.UserState as DataField;

item.Content = townCombobox;

Binding editableBinding = new Binding() { ElementName = "customerDataForm", Path = new PropertyPath("Mode"), Converter = new InverseModeConvertor() };

item.SetBinding(DataField.IsReadOnlyProperty, editableBinding);

}

private void customerDataForm_DeletingItem(object sender, System.ComponentModel.CancelEventArgs e)

{

var ctx = customerDomainDataSource.DomainContext as DomainService1;

DataForm form = sender as DataForm;

form.CommitEdit();

Customer ev = form.CurrentItem as Customer;

ctx.Customers.Remove(ev);

ctx.SubmitChanges((op) =>

{

if (op.HasError)

{

MessageBox.Show(op.Error.Message);

}

}, null);

}

}

}

Добавим на основную форму кнопку, которая будет открывать форму с данными:

private void btnView_Click(object sender, RoutedEventArgs e)

{

CustomerView view = new CustomerView(customerDataGrid.SelectedItem as Customer, customerDomainDataSource);

view.Show();

}

<UserControl

x:Class="BusinessApplication1.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"

xmlns:dataControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices" xmlns:my="clr-namespace:BusinessApplication1.Web.Services" xmlns:my1="clr-namespace:BusinessApplication.BLL">

<Grid x:Name="LayoutRoot" Style="{StaticResource LayoutRootGridStyle}">

<Border x:Name="ContentBorder" Style="{StaticResource ContentBorderStyle}">

<navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"

Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">

<navigation:Frame.UriMapper>

<uriMapper:UriMapper>

<uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>

<uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>

</uriMapper:UriMapper>

</navigation:Frame.UriMapper>

</navigation:Frame>

</Border>

<Grid Style="{StaticResource NavigationOuterGridStyle}">

<Grid x:Name="NavigationGrid" Style="{StaticResource NavigationGridStyle}">

<Border x:Name="BrandingBorder" Style="{StaticResource BrandingBorderStyle}">

<StackPanel x:Name="BrandingStackPanel" Style="{StaticResource BrandingStackPanelStyle}">

<ContentControl Style="{StaticResource LogoIcon}"/>

<TextBlock x:Name="ApplicationNameTextBlock" Style="{StaticResource ApplicationNameStyle}"

Text="{Binding ApplicationStrings.ApplicationName, Source={StaticResource ResourceWrapper}}"/>

</StackPanel>

</Border>

<Border x:Name="LinksBorder" Style="{StaticResource LinksBorderStyle}">

<StackPanel x:Name="LinksStackPanel" Style="{StaticResource LinksStackPanelStyle}">

<HyperlinkButton x:Name="Link1" Style="{StaticResource LinkStyle}"

NavigateUri="/Home" TargetName="ContentFrame" Content="{Binding Path=ApplicationStrings.HomePageTitle, Source={StaticResource ResourceWrapper}}"/>

<Rectangle x:Name="Divider1" Style="{StaticResource DividerStyle}"/>

<HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}"

NavigateUri="/About" TargetName="ContentFrame" Content="{Binding Path=ApplicationStrings.AboutPageTitle, Source={StaticResource ResourceWrapper}}"/>

</StackPanel>

</Border>

</Grid>

<Border x:Name="loginContainer" Style="{StaticResource LoginContainerStyle}">

<!-- LoginStatus will be added here in code behind. This is required for the designer view to work -->

</Border>

<StackPanel>

<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ElementName=customerDomainDataSource, Path=Data}" Margin="0,123,0,0" Name="customerDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="400">

<sdk:DataGrid.Columns>

<sdk:DataGridTextColumn x:Name="iDColumn" Binding="{Binding Path=ID, Mode=OneWay}" Header="ID" IsReadOnly="True" Width="SizeToHeader" />

<sdk:DataGridTextColumn x:Name="nameColumn" Binding="{Binding Path=Name}" Header="Name" Width="SizeToHeader" />

<sdk:DataGridTextColumn x:Name="townIDColumn" Binding="{Binding Path=TownID}" Header="Town ID" Width="SizeToHeader" />

</sdk:DataGrid.Columns>

</sdk:DataGrid>

<Button Name="btnView" Content="View" Click="btnView_Click" Width="120"></Button>

<dataControls:DataForm CurrentItem="{Binding ElementName=customerDataGrid, Path=SelectedItem, Mode=TwoWay}"

AutoGenerateFields="True"

AutoCommit="False"

AutoEdit="False"

Width="400"

EditEnded="DataForm_EditEnded"

AutoGeneratingField="DataForm_AutoGeneratingField"

Name="customerDataForm"

CommandButtonsVisibility="All"

ItemsSource="{Binding Path=Data, ElementName=customerDomainDataSource}"

DeletingItem="customerDataForm_DeletingItem">

</dataControls:DataForm>

</StackPanel>

</Grid>

<riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my1:Customer, CreateList=true}" Height="0" LoadedData="customerDomainDataSource_LoadedData" Name="customerDomainDataSource" QueryName="GetCustomersQuery" Width="0">

<riaControls:DomainDataSource.DomainContext>

<my:DomainService1 />

</riaControls:DomainDataSource.DomainContext>

</riaControls:DomainDataSource>

</Grid>

</UserControl>

Получится такое модальное окно:

clip_image002

Теперь пришло время исправить наш DataGrid так, чтобы он не показывал ненужные колонки, а также показывал название города вместо его идентификатора. Это очень просто, для этого нужно только изменить немного описание колонок грида, к счастью, колонки генерируются не во время выполнения.

<UserControl

x:Class="BusinessApplication1.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"

xmlns:dataControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices" xmlns:my="clr-namespace:BusinessApplication1.Web.Services" xmlns:my1="clr-namespace:BusinessApplication.BLL">

<Grid x:Name="LayoutRoot" Style="{StaticResource LayoutRootGridStyle}">

<Border x:Name="ContentBorder" Style="{StaticResource ContentBorderStyle}">

<navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"

Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">

<navigation:Frame.UriMapper>

<uriMapper:UriMapper>

<uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>

<uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>

</uriMapper:UriMapper>

</navigation:Frame.UriMapper>

</navigation:Frame>

</Border>

<Grid Style="{StaticResource NavigationOuterGridStyle}">

<Grid x:Name="NavigationGrid" Style="{StaticResource NavigationGridStyle}">

<Border x:Name="BrandingBorder" Style="{StaticResource BrandingBorderStyle}">

<StackPanel x:Name="BrandingStackPanel" Style="{StaticResource BrandingStackPanelStyle}">

<ContentControl Style="{StaticResource LogoIcon}"/>

<TextBlock x:Name="ApplicationNameTextBlock" Style="{StaticResource ApplicationNameStyle}"

Text="{Binding ApplicationStrings.ApplicationName, Source={StaticResource ResourceWrapper}}"/>

</StackPanel>

</Border>

<Border x:Name="LinksBorder" Style="{StaticResource LinksBorderStyle}">

<StackPanel x:Name="LinksStackPanel" Style="{StaticResource LinksStackPanelStyle}">

<HyperlinkButton x:Name="Link1" Style="{StaticResource LinkStyle}"

NavigateUri="/Home" TargetName="ContentFrame" Content="{Binding Path=ApplicationStrings.HomePageTitle, Source={StaticResource ResourceWrapper}}"/>

<Rectangle x:Name="Divider1" Style="{StaticResource DividerStyle}"/>

<HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}"

NavigateUri="/About" TargetName="ContentFrame" Content="{Binding Path=ApplicationStrings.AboutPageTitle, Source={StaticResource ResourceWrapper}}"/>

</StackPanel>

</Border>

</Grid>

<Border x:Name="loginContainer" Style="{StaticResource LoginContainerStyle}">

<!-- LoginStatus will be added here in code behind. This is required for the designer view to work -->

</Border>

<StackPanel>

<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ElementName=customerDomainDataSource, Path=Data}" Margin="0,123,0,0" Name="customerDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top" Width="400">

<sdk:DataGrid.Columns>

<sdk:DataGridTextColumn x:Name="nameColumn" Binding="{Binding Path=Name}" Header="Name" Width="SizeToHeader" />

<sdk:DataGridTextColumn x:Name="townIDColumn" Binding="{Binding Path=Town.Name}" Header="Town" Width="SizeToHeader" />

</sdk:DataGrid.Columns>

</sdk:DataGrid>

<Button Name="btnView" Content="View" Click="btnView_Click" Width="120"></Button>

<dataControls:DataForm CurrentItem="{Binding ElementName=customerDataGrid, Path=SelectedItem, Mode=TwoWay}"

AutoGenerateFields="True"

AutoCommit="False"

AutoEdit="False"

Width="400"

EditEnded="DataForm_EditEnded"

AutoGeneratingField="DataForm_AutoGeneratingField"

Name="customerDataForm"

CommandButtonsVisibility="All"

ItemsSource="{Binding Path=Data, ElementName=customerDomainDataSource}"

DeletingItem="customerDataForm_DeletingItem">

</dataControls:DataForm>

</StackPanel>

</Grid>

<riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my1:Customer, CreateList=true}" Height="0" LoadedData="customerDomainDataSource_LoadedData" Name="customerDomainDataSource" QueryName="GetCustomersQuery" Width="0">

<riaControls:DomainDataSource.DomainContext>

<my:DomainService1 />

</riaControls:DomainDataSource.DomainContext>

</riaControls:DomainDataSource>

</Grid>

</UserControl>

Комментариев нет:

Отправить комментарий