2012年3月23日 星期五

[Silverlight] CombBox技巧演示(方法三):解決ComboBox在DataGrid內,如何設定預設值於對應CellTemplate中的TextBlock

我在[Silverlight] CombBox技巧演示(方法一)的文章中,只教授了如何在ComboBox選擇了項目後,刷新對應的TextBlock,並沒有提供方法去解決ComboBox與對應TextBlock的預設值問題。因此,我把程序碼稍為修改一下,於介面開始載入時,設定預設值於ComboBox。然後運用DataGrid的LoadingRow事件,去刷新DataGrid每行列中ComboBox對應的TextBlock。


詳細的程序碼如下:

MainPage.xaml

   1:  <UserControl x:Class="SlComboSample1_2.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:      <Grid x:Name="LayoutRoot" Background="White">
  10:          <sdk:DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" 
  11:                        Margin="24,12,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="364" 
  12:                        Height="276" CellEditEnded="dataGrid1_CellEditEnded" LoadingRow="dataGrid1_LoadingRow">
  13:              <sdk:DataGrid.Columns>
  14:                  <sdk:DataGridTemplateColumn CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="Auto" Header="PATIENT NAME" >
  15:                      <sdk:DataGridTemplateColumn.CellTemplate>
  16:                          <DataTemplate>
  17:                              <TextBlock Text="{Binding PatientName}" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBlock1" VerticalAlignment="Top" />
  18:                          </DataTemplate>
  19:                      </sdk:DataGridTemplateColumn.CellTemplate>
  20:                      <sdk:DataGridTemplateColumn.CellEditingTemplate>
  21:                          <DataTemplate>
  22:                              <ComboBox ItemsSource="{Binding }" SelectedValuePath="PatientID" DisplayMemberPath="Name" SelectedValue="{Binding Patient,Mode=TwoWay}" Loaded="comboBox2_Loaded" Height="23" HorizontalAlignment="Left" Margin="10,43,0,0" Name="comboBox2" VerticalAlignment="Top" Width="120" />
  23:                          </DataTemplate>
  24:                      </sdk:DataGridTemplateColumn.CellEditingTemplate>
  25:                  </sdk:DataGridTemplateColumn>
  26:                  <sdk:DataGridTextColumn Binding="{Binding DiagnosisResult,Mode=TwoWay}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Diagnosis Result" Width="Auto" />
  27:              </sdk:DataGrid.Columns>
  28:          </sdk:DataGrid>
  29:      </Grid>
  30:  </UserControl>

以下是MainPage.xaml背後的cs程序碼,其重點是首先在MainPage()內設定ComboBox的預設值及繫到Datagrid,接著要加程序碼於dataGrid1_LoadingRow事件,該事件是用來把ComboBox預設值以linq方式與patientList作配對去找出對應的TextBlock值,該事件會在DataGrid載入每一行列時被引發一次,(例如:在本示例中DataGrid共有三行列,即dataGrid1_LoadingRow事件會被引發三次。) 而事件中利用e.Row.GetIndex()去找出當中的列,並運用linq去找出該行ComboBox預設值所對應的TextBlock值。

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:  namespace SlComboSample1_2
   8:  {
   9:      public partial class MainPage : UserControl
  10:      {
  11:          List<Patient> patientList;
  12:   
  13:          public MainPage()
  14:          {
  15:              InitializeComponent();
  16:              // 新增四筆記錄到Patient類別,該類別用作ComboBox的選項來源
  17:              patientList = new List<Patient>();
  18:              patientList.Add(new Patient(1, "John"));
  19:              patientList.Add(new Patient(2, "Sam"));
  20:              patientList.Add(new Patient(3, "Barry"));
  21:              patientList.Add(new Patient(4, "Ken"));
  22:   
  23:              // 新增三筆Diagnosis記錄到DataGrid
  24:              List<Diagnosis> DiagnosisList = new List<Diagnosis>();
  25:              DiagnosisList.Add(new Diagnosis());
  26:              DiagnosisList.Add(new Diagnosis());
  27:              DiagnosisList.Add(new Diagnosis());
  28:   
  29:              //設定所有Diagnosis記錄的預設值為Barry
  30:              foreach (Diagnosis d in DiagnosisList)
  31:              {
  32:                  d.Patient = 3;
  33:              }
  34:              dataGrid1.ItemsSource = DiagnosisList;
  35:              dataGrid1.CanUserSortColumns = false;
  36:   
  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:                  {
  52:                      Diagnosis row = (Diagnosis)e.Row.DataContext;
  53:                      row.PatientName = Convert.ToString(patientname.ToList()[0]);
  54:                  }
  55:              }
  56:          }
  57:   
  58:          private void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e)
  59:          {
  60:              //在DataGrid載入每行列時引發更新CellTemplate內TexkBlock的值
  61:              List<Diagnosis> dgList = ((DataGrid)sender).ItemsSource as List<Diagnosis>;
  62:              var patientname = from p in (patientList.AsQueryable()) where p.PatientID == (dgList[e.Row.GetIndex()].Patient) select p.Name;
  63:              if (patientname.ToList().Count > 0)
  64:              {
  65:                  Diagnosis row = (Diagnosis)e.Row.DataContext;
  66:                  row.PatientName = Convert.ToString(patientname.ToList()[0]);
  67:              }
  68:          }
  69:      }
  70:   
  71:      public class Diagnosis
  72:      {
  73:          private int patient;
  74:          private string diagnosisResult;
  75:          private string patientName;
  76:   
  77:          public Diagnosis()   // 提供給DataGrid的資料來源類別
  78:          {
  79:              patient = 0;  // 預設ComboBox的在Page開始時沒有選任何項目
  80:              diagnosisResult = null;
  81:          }
  82:   
  83:          public int Patient { get { return patient; } set { patient = value; } }
  84:          public string PatientName { get { return patientName; } set { patientName = value; } }
  85:          public string DiagnosisResult { get { return diagnosisResult; } set { diagnosisResult = value; } }
  86:      }
  87:   
  88:      public class Patient         // 提供給ComboBox 的選項來源類別
  89:      {
  90:          private int patientID;
  91:          private string name;
  92:   
  93:          public Patient(int PatientID, string Name)
  94:          {
  95:              patientID = PatientID;
  96:              name = Name;
  97:          }
  98:          public int PatientID { get { return patientID; } set { patientID = value; } }
  99:          public string Name { get { return name; } set { name = value; } }
 100:      }
 101:  }

完整程序碼下載地址:
https://docs.google.com/open?id=0BxRiNrIXEFArQkNUSXE1ZXRTRzZ1cHBvUjAtV3Fkdw

沒有留言:

張貼留言