2012年3月18日 星期日

[Silverlight] CombBox技巧演示(方法二):解決在DataGrid內的CellEditingTemplate中選了ComboBox值後,刷新對應CellTemplate內TextBlock的值

在上一篇的文章中,我用了DataGrid的CellEditEnd事件來引發刷新CellTemplate內TextBlock的值。其實亦可用另一個方法解決,就是在自定的類別中透過 INotifyPropertyChanged 介面,去刷新TextBlock。

記得我在初學Silverlight的時候了解到要使用System.ComponentModel的命名空間實作 INotifyPropertyChanged 介面於自定的類別,並把它繫結到DataGrid。以下程式碼就是示列,在DataGrid1所繫結的Diagnosis 類別實施 INotifyPropertyChanged 介面,並且Diagnosis物件中的Patient屬性會繫結相關CellEditingTemplate內的ComboBox。因此,可在Patient屬性內加上程式碼去轉換出對應的CellTemplate中TextBlock的值。由於轉換過程中要以ComboBox的資料項目來源作比較,所以我亦在Diagnosis物件中以ObservableCollection<Patient> patientList這集合來儲存ComboBox的數據源。然後轉換出來的值儲存於Diagnosis物件中的patientName屬性,並繫結到對應CellTemplate內的TextBlock。


頁面 .xaml 程式碼 ---

Code:
<UserControl x:Class="SlComboSample1_1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

    <Grid x:Name="LayoutRoot" Background="White">

        <sdk:DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="24,22,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="346" Height="253">

            <sdk:DataGrid.Columns>

                <sdk:DataGridTemplateColumn CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="Auto" Header="PATIENT NAME" >

                    <sdk:DataGridTemplateColumn.CellTemplate>

                        <DataTemplate>

                            <TextBlock Text="{Binding PatientName,Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="textBlock1" VerticalAlignment="Top" />

                        </DataTemplate>

                    </sdk:DataGridTemplateColumn.CellTemplate>

                    <sdk:DataGridTemplateColumn.CellEditingTemplate>

                        <DataTemplate>

                            <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" />

                        </DataTemplate>

                    </sdk:DataGridTemplateColumn.CellEditingTemplate>

                </sdk:DataGridTemplateColumn>

                <sdk:DataGridTextColumn Binding="{Binding DiagnosisResult,Mode=TwoWay}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Diagnosis Result" Width="Auto" />

            </sdk:DataGrid.Columns>

        </sdk:DataGrid>

    </Grid>    

</UserControl>


背後的 .xaml.cs 的程式碼 ---

Code:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace SlComboSample1_1
{
    public partial class MainPage : UserControl
    {
        ObservableCollection<Patient> patientList;

        public MainPage()
        {
            InitializeComponent();

            // 新增四筆記錄到Patient類別,該類別用作ComboBox的選項來源
            patientList = new ObservableCollection<Patient>();
            patientList.Add(new Patient(1, "John"));
            patientList.Add(new Patient(2, "Sam"));
            patientList.Add(new Patient(3, "Barry"));
            patientList.Add(new Patient(4, "Ken"));

            // 新增三筆Diagnosis記錄到DataGrid
            ObservableCollection<Diagnosis> DiagnosisList = new ObservableCollection<Diagnosis>();
            DiagnosisList.Add(new Diagnosis());
            DiagnosisList.Add(new Diagnosis());
            DiagnosisList.Add(new Diagnosis());
            DiagnosisList[0].PatientList = patientList;
            DiagnosisList[1].PatientList = patientList;
            DiagnosisList[2].PatientList = patientList;
            dataGrid1.ItemsSource = DiagnosisList;
        }

        private void comboBox2_Loaded(object sender, RoutedEventArgs e)
        {
            ((ComboBox)sender).ItemsSource = patientList; //把patientList的集合繫結到ComboBox
        }
    }


    public class Diagnosis : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private int patient;
        private string diagnosisResult;
        private string patientName;
        private ObservableCollection<Patient> patientList;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }


        public Diagnosis()   // 提供給DataGrid的資料來源類別
         {
            patient = 0;  // 預設ComboBox的在Page開始時沒有選任何項目

              patientName = String.Empty;
            diagnosisResult = String.Empty;
        }


        public int Patient
        {
            get { return patient; }

            set
            {
                if (value != this.patient)
                {
                    patient = value;

                    if (patientList != null)
                    {
                        var pName = from p in (patientList.AsQueryable()) where p.PatientID == this.patient select p.Name;

                        if (pName.ToList().Count > 0)
                        {
                            this.patientName = Convert.ToString(pName.ToList()[0]);
                            NotifyPropertyChanged("PatientName");
                        }
                    }

                    NotifyPropertyChanged("Patient");
                }
            }
        }

        public string PatientName
        {
            get { return patientName; }

            set
            {
                if (value != this.patientName)
                {
                    patientName = value;
                    NotifyPropertyChanged("PatientName");
                }
            }
        }

        public string DiagnosisResult
        {
            get { return diagnosisResult; }

            set
            {
                if (value != this.diagnosisResult)
                {
                    diagnosisResult = value;
                    NotifyPropertyChanged("DiagnosisResult");
                }
            }
        }


        public ObservableCollection<Patient> PatientList
        {
            get { return patientList; }

            set
            {
                if (value != this.patientList)
                {
                    patientList = value;
                    NotifyPropertyChanged("PatientList");
                }
            }
        }
    }


    public class Patient    
    {
        private int patientID;
        private string name;

        public Patient(int PatientID, string Name)
        {
            patientID = PatientID;
            name = Name;
        }

        public int PatientID
        {
            get
            {
                return patientID;
            }

            set
            {
                patientID = value;
            }
        }

        public string Name { get { return name; } set { name = value; } }

    }
}



以下是程式碼下載地址:

沒有留言:

張貼留言