8

मेरे पास एक विनफॉर्म एप्लिकेशन है जो कुछ चीजों को हाइलाइट करने के लिए रंग का उपयोग करता है। मैं उपयोगकर्ताओं को 'उनके' रंग बदलने की अनुमति देना चाहता हूं। एक अभ्यास के रूप में, मैंने सोचा कि मैं रंगों के गुणों के साथ एक वर्ग का एक उदाहरण बनाउंगा, और इसे एक संपत्ति ग्रिड (एक अच्छा संपादक प्राप्त करने के लिए) असाइन करें।PropertyGrid कोड में गुणों को परिवर्तित नहीं करता है?

यह ठीक काम करता प्रतीत होता है, लेकिन मैंने सोचा कि मैं उपयोगकर्ताओं को रंगों को रीसेट करने और उन्हें बेज के 20 रंगों में सेट करने के बाद) को रीसेट करना चाहता हूं। इसलिए, मैंने अपने फॉर्म में एक "रीसेट" बटन जोड़ा, जिसने मेरी ऑब्जेक्ट के रंग गुणों को डिफ़ॉल्ट पर वापस सेट किया।

हालांकि, ऐसा लगता है कि यह मेरे ऑब्जेक्ट की गुणों को वापस सेट करता है, तो संपत्ति ग्रिड नहीं बदलती है। अगर, रीसेट के बाद, मैं एक संपत्ति ग्रिड "ताज़ा करें" करता हूं, इसमें रीसेट रंग होता है।

मुझे लगता है कि संपत्ति ग्रिड यह नहीं जानता कि अंतर्निहित वस्तु बदल दी गई है?

क्या इस परिदृश्य में कुछ याद आ रही है, या क्या मुझे इसे स्वीकार करना चाहिए और जब मैं अपना ऑब्जेक्ट रीसेट करता हूं तो रीफ्रेश विधि को कॉल करना चाहिए?

धन्यवाद

(बहुत समान प्रश्न 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 प्रलेखीकरण यह कहें:

ग्रिड में प्रदर्शित जानकारी ऑब्जेक्ट असाइन किए जाने पर गुणों का एक स्नैपशॉट है। यदि चयनित ऑब्जेक्ट द्वारा निर्दिष्ट ऑब्जेक्ट का गुण मान रन टाइम पर कोड में बदल दिया गया है, तो नया मान तब तक प्रदर्शित नहीं होता है जब तक ग्रिड में कोई कार्रवाई नहीं की जाती है ग्रिड को रीफ्रेश करने का कारण बनता है।

तो ऐसा लगता है कि PropertyGrid एक नियंत्रण नहीं है जो स्वत: अद्यतन करने योग्य है। मुझे लगता है कि इसका सुराग यह है कि प्रॉपर्टीग्रिड विधि का उपयोग विधि के बजाय SelectedObject विधि का उपयोग करता है, और बाद वाला यह इंगित करेगा कि यह शायद INotifyPropertyChanged को सुनता है।

आपको लार्सटेक ने सुझाव दिया है और ग्रिड को मैन्युअल रूप से रीफ्रेश करने के साथ छोड़ा गया है।

+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

हाय, धन्यवाद, कि काफी क्या मैं पहले से ही था है। मुझे अधिक दिलचस्पी थी कि संपत्ति ग्रिड खुद को क्यों नहीं देखता कि संपत्ति बदल गई है। कुछ भी नहीं (यानी प्रॉपर्टीग्रिड नियंत्रण) "PropertyChanged" ईवेंट की सदस्यता लेता है। ज़रूर ... मैं इसे अपने आप कर सकता हूं, जैसा आपके पास है, लेकिन क्यों? क्या यह हो सकता है कि PropertyGrid नियंत्रण में कोई बाध्य गुण नहीं है, इसलिए INotifyPropertyChanged ईवेंट को नहीं सुनता है? –

4

जो मैंने उपयोग किया था उसे याद रखने की कोशिश में इस प्रश्न में हुआ और सोचा कि यह दूसरों के लिए उपयोगी हो सकता है।

आप संपत्ति ग्रिड के अपडेट ट्रिगर करने के लिए [RefreshProperties] विशेषता का उपयोग कर सकते हैं।

जैसे:

[RefreshProperties(RefreshProperties.All)] 
    public int MyProperty{ get; set; } 
संबंधित मुद्दे