2012年3月30日 星期五

[Silverlight]元件秘訣(一):設置用戶介面成檢視模式的技巧

在開發一般商業應用程式,客戶常常都會要求我們能夠把用戶介面設置成為(Read only Mode or View Mode)唯讀或檢視模式,使某些用戶不應修改或編輯介面上的資料。而我們目標就是把所有介面上的元件都設置成不能打字或選項。

以下是範列的介面,包含了幾個按鈕,功能分別是:View Mode按鈕 -把整個介面設置成唯讀檢視模式。Lock Patient Name Column按鈕 - 只把DataGrid的Patient Name欄位設定成唯讀。Input Mode按鈕 - 把整個用戶介面還原成可編輯狀態。
以下是背後MainPage.xaml.cs 的源碼供參考:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Windows;
   5:  using System.Windows.Controls;
   6:   
   7:   
   8:  namespace ViewModeSample
   9:  {
  10:      public partial class MainPage : UserControl
  11:      {
  12:          List<Patient> patientList;
  13:   
  14:          public MainPage()
  15:          {
  16:              InitializeComponent();
  17:              // 新增四筆記錄到Patient類別,該類別用作ComboBox的選項來源
  18:              patientList = new List<Patient>();
  19:              patientList.Add(new Patient(1, "John"));
  20:              patientList.Add(new Patient(2, "Sam"));
  21:              patientList.Add(new Patient(3, "Barry"));
  22:              patientList.Add(new Patient(4, "Ken"));
  23:   
  24:              // 新增三筆Diagnosis記錄到DataGrid
  25:              List<Diagnosis> DiagnosisList = new List<Diagnosis>();
  26:              DiagnosisList.Add(new Diagnosis());
  27:              DiagnosisList.Add(new Diagnosis());
  28:              DiagnosisList.Add(new Diagnosis());
  29:   
  30:              //設定所有Diagnosis記錄的預設值為Barry
  31:              foreach (Diagnosis d in DiagnosisList)
  32:              {
  33:                  d.Patient = 3;
  34:              }
  35:              dataGrid1.ItemsSource = DiagnosisList;
  36:              dataGrid1.CanUserSortColumns = false;
  37:          }
  38:   
  39:          private void comboBox2_Loaded(object sender, RoutedEventArgs e)
  40:          {
  41:              ((ComboBox)sender).ItemsSource = patientList; //把patientList的集合繫結到ComboBox
  42:          }
  43:   
  44:          private void dataGrid1_CellEditEnded(object sender, DataGridCellEditEndedEventArgs e)
  45:          {
  46:              if (e.Column.Header.ToString().Equals("Patient Name"))
  47:              {
  48:                  List<Diagnosis> dList = ((DataGrid)sender).ItemsSource as List<Diagnosis>;
  49:                  var patientname = from p in (patientList.AsQueryable()) where p.PatientID == (dList[((DataGrid)sender).SelectedIndex].Patient) select p.Name;
  50:                  if (patientname.ToList().Count > 0)
  51:                      ((TextBlock)dataGrid1.Columns[0].GetCellContent(e.Row)).Text = Convert.ToString(patientname.ToList()[0]);
  52:              }
  53:          }
  54:   
  55:          private void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e)
  56:          {
  57:              //在DataGrid載入每行列時引發更新CellTemplate內TexkBlock的值
  58:              List<Diagnosis> dgList = ((DataGrid)sender).ItemsSource as List<Diagnosis>;
  59:              var patientname = from p in (patientList.AsQueryable()) where p.PatientID == (dgList[e.Row.GetIndex()].Patient) select p.Name;
  60:              if (patientname.ToList().Count > 0)
  61:                  ((TextBlock)dataGrid1.Columns[0].GetCellContent(e.Row)).Text = Convert.ToString(patientname.ToList()[0]);
  62:          }
  63:   
  64:   
  65:          private void ViewButton_Click(object sender, RoutedEventArgs e)
  66:          {
  67:              foreach (UIElement UI in LayoutRoot.Children)
  68:              {
  69:                  if (UI is TextBox)
  70:                      ((TextBox)UI).IsReadOnly = true;
  71:                  else if (UI is RichTextBox)
  72:                      ((RichTextBox)UI).IsReadOnly = true;
  73:                  else if (UI is CheckBox)
  74:                      ((CheckBox)UI).IsEnabled = false;
  75:                  else if (UI is ComboBox)
  76:                      ((ComboBox)UI).IsEnabled = false;
  77:                  else if (UI is ListBox)
  78:                      ((ListBox)UI).IsEnabled = false;
  79:                  else if (UI is Button)
  80:                  {
  81:                      if (((Button)UI).Name == "saveButton")
  82:                          ((Button)UI).Visibility = System.Windows.Visibility.Collapsed;
  83:                  }
  84:                  else if (UI is DataGrid)
  85:                  {
  86:                      foreach (DataGridColumn DBColl in ((DataGrid)UI).Columns)
  87:                          DBColl.IsReadOnly = true;
  88:                  }
  89:              }
  90:          }
  91:   
  92:          private void InputButton_Click(object sender, RoutedEventArgs e)
  93:          {
  94:              foreach (UIElement UI in LayoutRoot.Children)
  95:              {
  96:                  if (UI is TextBox)
  97:                      ((TextBox)UI).IsReadOnly = false;
  98:                  else if (UI is RichTextBox)
  99:                      ((RichTextBox)UI).IsReadOnly = false;
 100:                  else if (UI is CheckBox)
 101:                      ((CheckBox)UI).IsEnabled = true;
 102:                  else if (UI is ComboBox)
 103:                      ((ComboBox)UI).IsEnabled = true;
 104:                  else if (UI is ListBox)
 105:                      ((ListBox)UI).IsEnabled = true;
 106:                  else if (UI is Button)
 107:                  {
 108:                      if (((Button)UI).Name == "saveButton")
 109:                          ((Button)UI).Visibility = System.Windows.Visibility.Visible;
 110:                  }
 111:                  else if (UI is DataGrid)
 112:                  {
 113:                      foreach (DataGridColumn DBColl in ((DataGrid)UI).Columns)
 114:                          DBColl.IsReadOnly = false;
 115:                  }
 116:              }
 117:          }
 118:   
 119:          private void PatientNameLockButton_Click(object sender, RoutedEventArgs e)
 120:          {
 121:              dataGrid1.Columns[0].IsReadOnly = true;
 122:          }  
 123:      }
 124:   
 125:      public class Diagnosis
 126:      {
 127:          private int patient;
 128:          private string diagnosisResult;
 129:   
 130:          public Diagnosis()   // 提供給DataGrid的資料來源類別
 131:          {
 132:              patient = 0;  // 預設ComboBox的在Page開始時沒有選任何項目
 133:              diagnosisResult = null;
 134:          }
 135:   
 136:          public int Patient { get { return patient; } set { patient = value; } }
 137:          public string DiagnosisResult { get { return diagnosisResult; } set { diagnosisResult = value; } }
 138:      }
 139:   
 140:      public class Patient         // 提供給ComboBox 的選項來源類別
 141:      {
 142:          private int patientID;
 143:          private string name;
 144:   
 145:          public Patient(int PatientID, string Name)
 146:          {
 147:              patientID = PatientID;
 148:              name = Name;
 149:          }
 150:          public int PatientID { get { return patientID; } set { patientID = value; } }
 151:          public string Name { get { return name; } set { name = value; } }
 152:      }
153: }

以上的重點在於各按鈕的Click事件內的源碼,利用.Children去讀取頁面上所有元件的類型,再設置成唯讀,例如元件的類型是DataGrid的,便把其每個Column設置成唯讀。

以下是MainPage.xaml的源碼供參考:

   1:  <UserControl x:Class="ViewModeSample.MainPage"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:      mc:Ignorable="d"
   7:      d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
   8:   
   9:   
  10:          <Grid x:Name="LayoutRoot" Background="White">
  11:              <sdk:DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" 
  12:                        Margin="24,43,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="364" 
  13:                        Height="179" CellEditEnded="dataGrid1_CellEditEnded" LoadingRow="dataGrid1_LoadingRow">
  14:                  <sdk:DataGrid.Columns>
  15:                      <sdk:DataGridTemplateColumn CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="Auto" Header="Patient Name" >
  16:                          <sdk:DataGridTemplateColumn.CellTemplate>
  17:                              <DataTemplate>
  18:                                  <TextBlock Text="" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBlock1" VerticalAlignment="Top" />
  19:                              </DataTemplate>
  20:                          </sdk:DataGridTemplateColumn.CellTemplate>
  21:                          <sdk:DataGridTemplateColumn.CellEditingTemplate>
  22:                              <DataTemplate>
  23:                                  <ComboBox ItemsSource="{Binding }" SelectedValuePath="PatientID" DisplayMemberPath="Name" SelectedValue="{Binding Patient,Mode=TwoWay}" Loaded="comboBox2_Loaded" Height="23" HorizontalAlignment="Left" Margin="10,3,0,0" Name="comboBox2" VerticalAlignment="Top" Width="Auto" />
  24:                              </DataTemplate>
  25:                          </sdk:DataGridTemplateColumn.CellEditingTemplate>
  26:                      </sdk:DataGridTemplateColumn>
  27:                      <sdk:DataGridTextColumn Binding="{Binding DiagnosisResult,Mode=TwoWay}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Diagnosis Result" Width="Auto" />
  28:                  </sdk:DataGrid.Columns>
  29:              </sdk:DataGrid>
  30:              <Button Content="View Mode" Height="23" HorizontalAlignment="Left" Margin="301,228,0,0" Name="ViewButton" VerticalAlignment="Top" Width="87" Click="ViewButton_Click" />
  31:              <Button Content="Input Mode" Height="23" HorizontalAlignment="Left" Margin="211,228,0,0" Name="InputButton" VerticalAlignment="Top" Width="84" Click="InputButton_Click" />
  32:              <TextBox Height="23" HorizontalAlignment="Left" Margin="24,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
  33:              <Button Content="Save" Height="23" HorizontalAlignment="Left" Margin="24,228,0,0" Name="saveButton" VerticalAlignment="Top" Width="75" />
  34:              <Button Content="Lock Patient Name Column" Height="23" HorizontalAlignment="Left" Margin="211,257,0,0" Name="PatientNameLockButton" VerticalAlignment="Top" Width="177" Click="PatientNameLockButton_Click" />
  35:   
  36:          </Grid>
  37:  </UserControl>

完整範例下載地址
https://docs.google.com/open?id=0BxRiNrIXEFArUnJuWE1SUDBUeXVmMUpQWHptVk5mQQ

沒有留言:

張貼留言