Реализация шаблонов мастер страниц в Silverlight - Краткое описание каждого проекта
ОГЛАВЛЕНИЕ
Краткое описание каждого проекта
Имеются 4 проекта:
- DataObjectCollection : Структуры данных, используемые сервисом для соединения с клиентом
- CommandInMasterDaoWcf: Сервис, передающий данные от сервера к клиенту.
- CommandInMasterDemo : Проект приложения Silverlight.
Есть 3 основных элемента управления Silverlight, к которым нужно обратиться:
· LeftTreeViewMain – Древовидное меню
· Login Control – Страница входа в систему
· TopToolBar – Элемент управления, содержащий 11 управляющих кнопок
- CommandInMasterDemo.Web: Создается, когда вы создаете приложение Silverlight. Оно будет содержать управляющие элементы Silverlight, чтобы запускать их в браузере.
Рис 11. Проекты
Использование кода
Перед тем как мы начнем изучать пример, нужно описать несколько методов.
App.xaml.cs
Для классификации 4 состояний: начальное, поиск, изменение и клиентское
public enum WorkState
{
INT,//Начальное состояние
SEA,//Состояние поиска
MOD,//Состояние изменения
CUS,//Клиентское состояние
}
Получить или установить древовидное меню
public static System.Collections.ObjectModel.Collection<MenuDataContext> MenuList { get; set; }
Получить или установить идентификатор текущей формы
public static string CurrentFormID
{
get;
set;
}
В методе Application_Startup добавляется окно входа в систему RootVisual. Он будет создавать окно входа всистему при запуске.
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = rootVisual;
rootVisual.Children.Add(lg);
}
Мы используем отражение для создания экземпляра пользовательского элемента управления. Например, MainPage имеет пространство имен CommandInMasterDemo и имя класса MainPage, поэтому можно использовать отражение для создания объекта CommandInMasterDemo.MainPage, и затем преобразовать его в тип UserControl. Если пользовательский элемент управления не равен нулю, мы записываем в CurrentFormID strName, и затем добавляем пользовательский элемент управления в текущий Application.RootVisual.
public static void Navigate(string strName)
{
App CurrentApp = (App)Application.Current;
Type type = CurrentApp.GetType();
Assembly assembly = type.Assembly;
UserControl uc = (UserControl)assembly.CreateInstance(type.Namespace + "." + strName);
if (uc != null)
{
CurrentFormID = strName;
CurrentApp.rootVisual.Children.Clear();
CurrentApp.rootVisual.Children.Add((UserControl)assembly.CreateInstance(type.Namespace + "." + strName));
}
}
GetUserControl также использует отражение для создания экземпляра пользовательского элемента управления. Единственное различие между Navigate и GetUserControl – подготовка пространства имен. Все подстраницы имеют свою собственную папку подгруппы, такую как CHM, FCM. Поэтому нам нужно добавить имя подгруппы в пространство имен. Например, пользовательский элемент управления FCM201 имеет пространство имен CommandInMasterDemo.FCM и имя класса FCM201, поэтому мы используем type.Namespace + "." + strName.Substring(0, 3) + "." + strName, чтобы создать его экземпляр.
public static UserControl GetUserControl(string strName)
{
CurrentFormID = strName;
App CurrentApp = (App)Application.Current;
Type type = CurrentApp.GetType();
Assembly assembly = type.Assembly;
return (UserControl)assembly.CreateInstance(type.Namespace + "." + strName.Substring(0, 3) + "." + strName);
}
LoginControl.xaml.cs
Кнопка входа в систему запустит proxy_GetUserInfoCompleted, затем proxy_GetUserInfoCompleted запуститproxy_GetFunctionMenuCompleted
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(txtAccount.Text) || string.IsNullOrEmpty(txtPassword.Password))
{
txtErrorInformation.Text = "Account and Password must enter";
return;
}
else
{
this.Cursor = Cursors.Wait;
try
{
DaoWcfClient daoWcf = new DaoWcfClient();
daoWcf.GetUserInfoCompleted += new EventHandler<GetUserInfoCompletedEventArgs>(proxy_GetUserInfoCompleted);
daoWcf.GetUserInfoAsync(txtAccount.Text, txtPassword.Password);
}
catch (Exception ex)
{
MessageBox.Show("btnLogin_Click Exception: " + ex.Message);
}
finally
{
this.Cursor = Cursors.Arrow;
}
}
}
void proxy_GetUserInfoCompleted(object sender, GetUserInfoCompletedEventArgs e)
{
try
{
strCurrentUser = e.Result;
if (string.IsNullOrEmpty(strCurrentUser))
{
txtErrorInformation.Text = "Account or Password is incorrect";
}
else
{
Resources.Remove("CurrentUser");
Resources.Add("CurrentUser", txtAccount.Text);
Resources.Remove("CurrentDatabase");
Resources.Add("CurrentDatabase", cbDb.SelectionBoxItem.ToString());
DaoWcfClient daoWcf = new DaoWcfClient();
daoWcf.GetFunctionMenuCompleted += new EventHandler<GetFunctionMenuCompletedEventArgs>(proxy_GetFunctionMenuCompleted);
daoWcf.GetFunctionMenuAsync(txtAccount.Text);
}
}
catch (Exception ex)
{
MessageBox.Show("proxy_FindUserInfoCompleted Exception: " + ex.Message);
}
}
void proxy_GetFunctionMenuCompleted(object sender, GetFunctionMenuCompletedEventArgs e)
{
System.Collections.ObjectModel.Collection<MenuDataContext> list = e.Result;
if (list.Count > 0)
{
App CurrentApp = (App)Application.Current;
App.MenuList = list;
App.Navigate("MainPage");
}
}
Давайте изучим proxy_GetUserInfoCompleted. Мы сохраняем идентификатор пользователя и имя системы, используя Ресурсы.
Resources.Remove("CurrentUser");
Resources.Add("CurrentUser", txtAccount.Text);
Resources.Remove("CurrentDatabase");
Resources.Add("CurrentDatabase", cbDb.SelectionBoxItem.ToString());
В proxy_GetFunctionMenuCompleted после получения списка меню мы сохраняем список меню в свойстве App MenuList, затем используем App.Navigate, чтобы перейти на Главную страницу.
System.Collections.ObjectModel.Collection<MenuDataContext> list = e.Result;
if (list.Count > 0)
{
App CurrentApp = (App)Application.Current;
App.MenuList = list;
App.Navigate("MainPage");
}
Мы создали делегат MenuEventHandler(object sender, RouteEventArgs e) для всех кнопок управления.
public delegate void MenuEventHandler(object sender, RoutedEventArgs e);
Каждая кнопка управления имеет свое собственное событие
public event MenuEventHandler SearchClick;
public event MenuEventHandler ExecuteClick;
public event MenuEventHandler EditClick;
public event MenuEventHandler DeleteClick;
public event MenuEventHandler SaveClick;
public event MenuEventHandler LastClick;
public event MenuEventHandler FirstClick;
public event MenuEventHandler PreviousClick;
public event MenuEventHandler NextClick;
public event MenuEventHandler ExcelClick;
Имеется 3 свойства:
- Текущее состояние : Получить/установить текущие состояния
public WorkState CurrentState
{
get
{
return curretState;
}
set
{
curretState = value;
SetButtonState();
}
}
- BindGrid : Получить/Установить элемент управления DataGrid (сетка данных), чтобы он мог взаимодействовать с кнопками Первая, Предыдущая, Следующая и Последняя.
public DataGrid BindGrid { get; set; }
- TotalRowCount (общее число строк) : Получить/Установить общее число записей данных
public int TotalRowCount { get; set; }
SetButtonState (установить состояние кнопки) используется, чтобы скрыть/показать кнопки управления в различных состояниях.
private void SetButtonState()
{
switch (CurrentState)
{
case WorkState.INT:
txtStatus.Text = "Initial";
//Поиск
btnSearch.IsEnabled = true;
imgbtnSearchOn.Visibility = Visibility.Visible;
...............
break;
case WorkState.SEA:
txtStatus.Text = "Search";
//Поиск
btnSearch.IsEnabled = true;
imgbtnSearchOn.Visibility = Visibility.Visible;
...............
break;
case WorkState.MOD:
txtStatus.Text = "Modify";
//Поиск
btnSearch.IsEnabled = true;
imgbtnSearchOn.Visibility = Visibility.Visible;
...............
break;
case WorkState.CUS:
txtStatus.Text = "Custom";
break;
default:
txtStatus.Text = "Search";
//Поиск
btnSearch.IsEnabled = true;
imgbtnSearchOn.Visibility = Visibility.Visible;
...............
break;
}
}
Есть два способа включить 4 кнопки перемещения записей (Первая, Предыдущая, Следующая и Последняя). Одна для взаимодействия с элементом управления DataGrid, другая для его запуска в подстранице.
private void btnLast_Click(object sender, RoutedEventArgs e)
{
if (BindGrid != null)
{
BindGrid.SelectedIndex = TotalRowCount - 1;
}
else
{
LastClick(this, e);
}
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
if (BindGrid != null)
{
if (BindGrid.SelectedIndex != TotalRowCount - 1)
{
BindGrid.SelectedIndex = BindGrid.SelectedIndex + 1;
}
}
else
{
NextClick(this, e);
}
}
private void btnPrevious_Click(object sender, RoutedEventArgs e)
{
if (BindGrid != null)
{
if (BindGrid.SelectedIndex != 0)
{
BindGrid.SelectedIndex = BindGrid.SelectedIndex - 1;
}
}
else
{
PreviousClick(this, e);
}
}
private void btnFirst_Click(object sender, RoutedEventArgs e)
{
if (BindGrid != null)
{
BindGrid.SelectedIndex = 0;
}
else
{
FirstClick(this, e);
}
}
CommonUtility.cs
Чтобы получить элемент управления TopToolBar, сначала нужно найти элемент управления MainPage, потому что MainPage содержит TopToolBar.
public MainPage GetMainPage(UserControl currentPage, bool blSub)
{
MainPage mainPage = blSub ? (MainPage)((Grid)((Grid)((Grid)currentPage.Parent).Parent).Parent).Parent : (MainPage)((Grid)((Grid)currentPage.Parent).Parent).Parent;
return mainPage;
}
После того как мы нашли элемент управления MainPage, можно использовать метод FindName (найти имя),чтобы получить элемент управления TopToolBar.
public GetTopToolBar(UserControl currentPage, bool blSub)
{
ttb = GetMainPage(currentPage, blSub).FindName("topToolBar") as ;
return ttb;
}
ExportExcel.ashx.cs
The Silverlight не имеет возможности сохранить файл на локальный диск, поэтому используется обработчик для создания файла CSV/Excel.
public void ProcessRequest(HttpContext context)
{
string strContext = context.Request.QueryString["Context"] != null ?
HttpUtility.UrlDecode(context.Request.QueryString["Context"]) : DateTime.Now.ToString("yyyyMMdd_HHmmss");
string[] strSplit = strContext.Replace("[", "").Replace("]", "").Split(char.Parse(";"));
string strFileName = strSplit[0];
string strQueryCase = strSplit[1];
DataGrid dg = new DataGrid();
switch (strQueryCase)
{
case "FindMTAccntScopeByYear":
List<AccountDataContext> list = new ().GetAccountByYear(strSplit[2]);
dg.DataSource = list;
break;
case "FindAllyCompAccountByOwnerId":
List<AllyCompAcctDataContext> listAlly = new DaoWcf().GetAllyCompAccountByOwnerId(strSplit[2]);
dg.DataSource = listAlly;
break;
}
dg.DataBind();
context.Response.Buffer = true;
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.ContentType = "application/vnd.ms-excel";
context.Response.AddHeader("content-disposition", "attachment;filename=" + strFileName + ".xls");
dg.HeaderStyle.ForeColor = Color.Blue;
dg.HeaderStyle.BackColor = Color.White;
dg.ItemStyle.BackColor = Color.White;
System.IO.StringWriter tw = new StringWriter();
System.Web.UI.HtmlTextWriter hw = new HtmlTextWriter(tw);
dg.RenderControl(hw);
context.Response.Write(tw.ToString());
context.Response.Flush();
context.Response.Close();
context.Response.End();
}