12

色を使用して特定のものを強調表示するWinformアプリケーションがあります。ユーザーが「自分の」色を変更できるようにしたいと思います。演習として、色のプロパティを使用してクラスのインスタンスを作成し、それをプロパティグリッドに割り当てると思いました(優れたエディターを取得するため)

これは問題なく機能しているようですが、ユーザーが色をリセットできるようにしたいと思いました(ユーザーがいじって、ベージュの20色に設定した後)。そこで、フォームに「リセット」ボタンを追加しました。これにより、オブジェクトの色のプロパティがデフォルトに戻ります。

ただし、オブジェクトのプロパティを元に戻しても、プロパティグリッドは変更されないようです。リセット後にプロパティグリッド「更新」を実行すると、リセットされた色になります。

プロパティグリッドは、基になるオブジェクトが変更されたことを認識していないと思いますか?

このシナリオに欠けているものはありますか、それともオブジェクトをリセットするときにそれを受け入れてRefreshメソッドを呼び出す必要がありますか?

ありがとう

(ここで非常によく似た質問)

public partial class Form1 : Form
{
  public Form1()
  {
     InitializeComponent();

     this.propertyGrid1.SelectedObject = new Colours();
  }

  private void button1_Click(object sender, EventArgs e)
  {
     Colours colours = this.propertyGrid1.SelectedObject as Colours;
     colours.Reset();
  }
}

public partial class Colours : INotifyPropertyChanged 
{
  public event PropertyChangedEventHandler PropertyChanged;

  public Color ColourP1 { get; set; }

  public void Reset()
  {
     this.ColourP1 = Color.Red;
     var handler = this.PropertyChanged;
     if (handler != null) handler(this, new PropertyChangedEventArgs("ColourP1"));
  }
}

「INotifyPropertyChanged.PropertyChangedにサブスクライブするものはありません」という私のコメントに続いて、PropertyGridコントロールをサブクラス化してサブクラス化することの欠点は何ですか?

public partial class MyPropertyGrid : System.Windows.Forms.PropertyGrid
{
  private INotifyPropertyChanged _selectedObject;

  protected override void OnSelectedObjectsChanged(EventArgs e)
  {
     base.OnSelectedObjectsChanged(e);

     if (_selectedObject != null) _selectedObject.PropertyChanged -= selectedObject_PropertyChanged;
     _selectedObject = this.SelectedObject as INotifyPropertyChanged;
     if (_selectedObject != null) _selectedObject.PropertyChanged += selectedObject_PropertyChanged;
  }

  private void selectedObject_PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
     this.Refresh();
  }
}
4

5 に答える 5

14

PropertyGridが変更されない理由に関する質問に答えるために、 PropertyGridのMSDNドキュメントには次のように記載されています。

グリッドに表示される情報は、オブジェクトが割り当てられたときのプロパティのスナップショットです。SelectedObjectによって指定されたオブジェクトのプロパティ値が実行時にコードで変更された場合、グリッドを更新するアクションがグリッドで実行されるまで、新しい値は表示されません。

したがって、PropertyGridは自動更新可能なコントロールではないようです。これの手がかりは、PropertyGridがSelectedObjectメソッドの代わりにメソッドを使用DataSourceすることであり、後者はおそらくINotifyPropertyChangedをリッスンすることを意味すると思います。

LarsTechが提案し、グリッドを手動で更新する必要があります。

于 2012-04-12T19:08:42.203 に答える
9

更新してみてください。

private void button1_Click(object sender, EventArgs e)
{
  Colours colours = this.propertyGrid1.SelectedObject as Colours;
  colours.Reset();
  this.propertyGrid1.Refresh();
}

PropertyChangedより多くのプロパティがあると仮定すると、イベントを使用できます。Colorクラスを次のように変更します。

public class Colours : INotifyPropertyChanged {
  public event PropertyChangedEventHandler PropertyChanged;

  private Color _ColourP1;

  public void Reset() {
    this.ColourP1 = Color.Red;
  }

  private void OnChanged(string propName) {
    if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs(propName));
  }

  public Color ColourP1 {
    get { return _ColourP1; }
    set {
      _ColourP1 = value;
      OnChanged("ColourP1");
    }
  }
}

次に、フォームは次のようになります。

public Form1() {
  InitializeComponent();

  Colours colours = new Colours();
  colours.PropertyChanged += colours_PropertyChanged;
  this.propertyGrid1.SelectedObject = colours;
}

private void colours_PropertyChanged(object sender, PropertyChangedEventArgs e) {
  this.propertyGrid1.Refresh();
}

private void button1_Click(object sender, EventArgs e) {
  ((Colours)this.propertyGrid1.SelectedObject).Reset();
}
于 2012-04-10T16:27:49.640 に答える
7

私が以前使っていたものを思い出そうとしてこの質問に出くわし、他の人にも役立つかもしれないと思いました。

[RefreshProperties]属性を使用して、プロパティグリッドの更新をトリガーできます。

例えば:

    [RefreshProperties(RefreshProperties.All)]
    public int MyProperty{ get; set; }
于 2016-10-26T15:06:40.950 に答える
0

DotNetBarAdvPropertyGridコントロールを使用します。iNotify更新するために電話をかける必要はありません。
オブジェクトのプロパティが変更されるたびに、グリッドが自動的に更新されます。

于 2019-08-24T15:07:03.777 に答える
0

.Net 4.7.2プロジェクトで、呼び出すyourPropGridInstanceHere.ExpandAllGridItems()と、プロパティグリッドが現在の「SelectedObject」に基づいて値を更新することがわかりました。

これは、collapseメソッドを呼び出さなくても実行できることに注意してください。

確かに、一部のカテゴリが折りたたまれている場合、これは機能しない可能性がありますが、少なくともより単純なケースでは、プロパティを実装しINotifyPropertChangedたり、絶えず更新したりする必要がなくなりSelectedObjectます。

私はまだ他の.Netバージョンでこれをテストしていませんが、それらすべてで機能すると思います。

于 2021-08-30T21:59:45.663 に答える