8

색상을 사용하여 특정 항목을 강조 표시하는 Winform 응용 프로그램이 있습니다. 사용자가 '자신의'색을 바꿀 수있게하고 싶습니다. 연습으로 색상의 속성을 가진 클래스의 인스턴스를 만들고 속성 격자 (좋은 편집기를 얻으려고)에 할당한다고 생각했습니다..PropertyGrid는 코드에서 변경된 속성을 알지 못합니까?

이것은 잘 작동하는 것처럼 보이지만, 사용자가 색상을 재설정하도록하려는 것입니다. (20 개의 베이지 색 음영으로 설정 한 후). 그래서, 내 개체의 색상 속성을 기본값으로 다시 설정하는 "재설정"단추를 양식에 추가했습니다.

그러나 내 개체의 속성을 다시 설정하는 동안 속성 표가 변경되지 않는 것으로 보입니다. 리셋 후에 속성 격자 "새로 고침"을 수행하면 재설정 된 색상이 적용됩니다.

속성 표가 기본 개체가 변경되었음을 알 수 없다고 가정합니다.

이 시나리오에서 누락 된 것이 있습니까? 아니면 그냥 받아 들여야하며 객체를 재설정 할 때 Refresh 메서드를 호출해야합니까?

감사

(매우 비슷한 질문 here) 의 내 댓글에 이어

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")); 
    } 
} 

는 subsclassing의 단점은 무엇, "아무것도 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(); 
    } 
} 

답변

9

는 PropertyGrid가 변경되지 않는 이유에 대한 귀하의 질문에 대답하기 위해, PropertyGrid에 대한 MSDN 설명서 다음과 같이 말하십시오 :

그리드에 표시되는 정보는 객체가 할당 된 시점의 속성의 스냅 샷입니다. 런타임에 코드에서 SelectedObject에 의해 지정된 개체의 속성 값이 변경되면 그리드를 새로 고치기 작업이 수행 될 때까지 새 값이 표시되지 않습니다.

따라서 PropertyGrid는 자동 업데이트 가능한 컨트롤이 아닌 것으로 보입니다. 이 단서는 PropertyGrid가 DataSource 메서드 대신 SelectedObject 메서드를 사용하고 후자가 INotifyPropertyChanged를 수신한다는 것을 암시한다고 생각합니다.

LarsTech에서 제안하고 수동으로 그리드를 새로 고쳐야합니다.

+0

네, 꽤 많이 요약합니다. – LarsTech

6

그냥 새로 고침 :

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

더 많은 속성을해야합니다 가정, 당신은 당신의 PropertyChanged 이벤트를 사용할 수 있습니다. 나는이 같은 색상 클래스를 수정하는 것입니다 :

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(); 
} 
+0

안녕하세요, 감사, 즉 거의 내가 이미 가지고거야. 속성 그리드 자체가 속성이 변경되었음을 알지 못하는 이유에 더 관심이있었습니다. Nothing (즉, PropertyGrid 컨트롤)은 "PropertyChanged"이벤트를 구독합니다. 물론 ... 나도 할 수 있겠지만 왜 그래? PropertyGrid 컨트롤에 바인딩 된 속성이 없으므로 INotifyPropertyChanged 이벤트를 수신하지 않을 수 있습니까? –

4

내가 사용하던 것을 기억하려고 할 때이 질문 전체에서 발생하며 다른 사람들에게 유용 할 수 있다고 생각했습니다.

[RefreshProperties] 속성을 사용하여 속성 표에 대한 업데이트를 트리거 할 수 있습니다.

예 :

[RefreshProperties(RefreshProperties.All)] 
    public int MyProperty{ get; set; } 
관련 문제