- PR -

展開可能なプロパティの値変更をデザイナに通知する方法

1
投稿者投稿内容
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2005-02-02 18:06
現在勉強のために,
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconDesign-TimeForWindowsForms.asp

http://www.microsoft.com/japan/msdn/net/general/vsnetpropbrow.asp
を参考に単純なユーザコントロールを作成しています。
ユーザコントロールのプロパティに以下のようなクラスを追加しました。

[TypeConverter(typeof(PersonConverter)]
public class Person
{
 int age;
 string name;
 
 public Person(string name, int age){ this.name = name; this.age = age; }
 public Person() : this("名無し", 0){}
 
 public int Age
 {
  get{ return age; } set{ age = value; }
 }
 public string Name
 {
  get{ return name; } set{ name = value; }
 }
}
internal class PersonConverter : ExpandableObjectConverter
{
 // InstanceDescriptorからの変換やInstanceDescriptorへの変換処理
 // stringからの変換やstringへの変換処理
}

// ユーザコントロール
public class MyUserControl : UserControl
{
 private Person p = new Person();
 public Person P
 {
  get{ return p; }
  set
  {
   if(p != value)
   {
    p = value;
    // 値が変更されたら再描画
    this.Invalidate();
    this.Refresh();
   }
  }
 }
 
 private void OnPaint(object sender, EventArgs e)
 {
  // pクラスのNameとAgeの値を描画する
 }
}

コントロールには,PersonクラスのプロパティPがあます。コントロールは,そのPプロパティの内容を画面に表示するというものです。
このコントロールをFormに載せて,Pプロパティの値をプロパティウィンドウから普通に変更するとデザイナの表示は,再描画され意図したものになります。しかし,Pプロパティを展開してNameプロパティをAgeプロパティを変更した場合はデザイナが再描画されません。
どのようにすれば再描画されるようになるでしょうか?

試してみた事
・Pプロパティに[NotifyParentProperty(true)]や[RefreshProperties(RefreshProperties.Repaint)]属性をつけてみた
・Pプロパティのsetの部分のif文を取り除いて常に再描画を行うようにしてみた
・PersonクラスのAgeプロパティとNameプロパティに[NotifyParentProperty(true)]や[RefreshProperties(RefreshProperties.Repaint)]属性をつけてみた
・MyUserControlにpublic event EventHandler OnPChanged;というイベントをつけてみた
・Personクラスにpublic event EventHandler OnNameChanged, OnAgeChangedイベントをつけてみた
にしざき
ぬし
会議室デビュー日: 2003/06/30
投稿数: 304
投稿日時: 2005-02-02 22:07
> ・Personクラスにpublic event EventHandler OnNameChanged, OnAgeChangedイベントをつけてみた
脇道ですが、イベント名には On をつけないことが推奨されています。
MyUserControl で
コード:
 // どこか(コンストラクタあたりか?)で
 p.NameChanged += new EventHandler(PersonNameChanged);
 p.AgeChanged += new EventHandler(PersonAgeChanged);

 private void PersonNameChanged(object sender, EventArgs e) {
  this.Invalidate();
 }

 private void PersonAgeChanged(object sender, EventArgs e) {
  this.Invalidate();
 }


とでもすれば、再描画されるはずです。

もちろん Name や Age が変わったら NameChanged や AgeChanged は発生させてくださいね。
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2005-02-02 23:58
引用:

脇道ですが、イベント名には On をつけないことが推奨されています。


うつす途中で書き間違えてました(^^;
 
NameやAgeの変更を外部に通知してそれを受け取る仕組みを作らないと駄目ですね。ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)