スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: スポンサー広告

DataGrid, 脱Reflection(弐)

脱Reflectionを目指すにあたり、以下のクラスを実装する。
  • TypeDescriptionProviderを継承したクラス:TwVMTypeDescriptionProvider
  • CustomTypeDescriptorを継承したクラス:TwVMTypeDescriptor
  • PropertyDescriptorを継承したクラス:TwVMPropertyDescriptor

    • クラス同士の関係としては、

      TwVMTypeDescriptionProvider
      ↓使う
      TwVMTypeDescriptor
      ↓使う
      TwVMPropertyDescriptor

      となるので、TwVMPropertyDescriptorから実装していく。

      PropertyDescriptorクラスはabstractクラスなので、abstractなメソッドやプロパティは実装が必須となる。
      using System;
      using System.ComponentModel;
      using System.Reflection;

      namespace TawamureDays.ComModels {

      /// <summary>
      /// TawamureDays ViewModel用プロパティ記述子クラス
      /// </summary>
      public class TwVMPropertyDescriptor : PropertyDescriptor {

      #region コンストラクタ

      /// <summary>
      /// コンストラクタ
      /// </summary>
      /// <param name="propertyInfo">プロパティ情報</param>
      public TwVMPropertyDescriptor(PropertyInfo propertyInfo) :
      base(propertyInfo.Name, (Attribute[])propertyInfo.
      GetCustomAttributes(typeof(Attribute),
      true)) {
      this.propertyInfo_ = propertyInfo;
      return;
      }

      #endregion

      #region PropertyDescriptor メンバー(プロパティ)

      /// <summary>
      /// プロパティが、ReadOnlyかどうかを取得します。
      /// </summary>
      public override bool IsReadOnly {
      get {return !propertyInfo_.CanWrite;}
      }

      /// <summary>
      /// プロパティが関連付けられているコンポーネントの型を取得します
      /// </summary>
      public override Type ComponentType {
      get {return propertyInfo_.DeclaringType;}
      }

      /// <summary>
      /// プロパティの型を取得します
      /// </summary>
      public override Type PropertyType {
      get {return this.propertyInfo_.PropertyType;}
      }

      #endregion

      #region ItemVMPropertyDescriptor メンバー(メソッド)

      /// <summary>
      /// コンポーネントをリセットしたときに、そのオブジェクトの値が変化するかどうかを示す値を返します
      /// </summary>
      /// <param name="component">コンポーネント</param>
      /// <returns>true:リセット可能, false:リセット不可能</returns>
      public override bool CanResetValue(object component) {
      return false;
      }

      /// <summary>
      /// コンポーネントのプロパティの値を既定値にリセットします。(未実装)
      /// </summary>
      /// <param name="component">コンポーネント</param>
      /// <exception cref="NotImplementedException">未実装のため必ず発生します。</exception>
      public override void ResetValue(object component) {
      throw new NotImplementedException();
      }

      /// <summary>
      /// プロパティの値を永続化する必要があるかどうかを示す値を決定します
      /// </summary>
      /// <param name="component">コンポーネント</param>
      /// <returns>true:永続化が必要, false:永続化は不要</returns>
      public override bool ShouldSerializeValue(object component) {
      return false;
      }

      /// <summary>
      /// プロパティが変更されたときに、ほかのオブジェクトに通知できるようにします
      /// </summary>
      /// <param name="component">コンポーネント</param>
      /// <param name="handler">ハンドラ</param>
      public override void AddValueChanged(object component, EventHandler handler) {
      //インターセプト用
      base.AddValueChanged(component, handler);
      }

      /// <summary>
      /// 引数オブジェクトと等しいかを判定します。
      /// </summary>
      /// <param name="obj">判定対象</param>
      /// <returns>true:等しい</returns>
      public override bool Equals(object obj) {
      TwVMPropertyDescriptor descriptor = obj as TwVMPropertyDescriptor;
      return descriptor != null && descriptor.propertyInfo_.Equals(this.propertyInfo_);
      }

      /// <summary>
      /// コンポーネントのプロパティの現在の値を取得します。
      /// </summary>
      /// <param name="component">コンポーネント</param>
      /// <returns>値</returns>
      public override object GetValue(object component) {
      //実装前。ここが肝心!
      //当クラスが対象とするプロパティから値を取得して返します。

      return null;
      }

      /// <summary>
      /// コンポーネントの値を別の値に設定します。
      /// </summary>
      /// <param name="component">コンポーネント</param>
      /// <param name="value">値</param>
      public override void SetValue(object component, object value) {
      //実装前。ここが肝心!
      //当クラスが対象とするプロパティへ引数の値(value)を設定します。


      //値の変更を通知ます。
      OnValueChanged(component,
      new PropertyChangedEventArgs(this.propertyInfo_.Name));
      return;
      }

      /// <summary>
      /// 特定の型のハッシュ関数として機能するための、コードを取得します。
      /// </summary>
      /// <returns>ハッシュコード</returns>
      public override int GetHashCode() {
      return this.propertyInfo_.GetHashCode();
      }

      #endregion

      #region 内部データ

      /// <summary>プロパティ情報</summary>
      private PropertyInfo propertyInfo_;

      #endregion
      }
      }
      肝心なのは、SetValueメソッドとGetValueメソッド。このメソッドが値を取得したり、設定したりするのに使用される。通常(標準)の実装だと、ここでReflectionを使うのだろう。ただし、それでは意味が無い。ここでReflectionを使わずに、且つそれよりも早い速度で取得や設定ができないと、実装する意味が無い。要するに、ここを実装できれば、脱Reflectionになれる。後の2クラスなんぞ、おまけである。
      じゃあ、どうやって取得或いは設定をするのかというと、あるクラスの某プロパティが欲しい時で実装した、式木バージョンの出番となる。
      続く。
      スポンサーサイト
      当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。