पर कॉल प्रेषित करने के लिए एक INotifyPropertyChanged प्रॉक्सी बनाना, मैं एक अलग (गैर-जीयूआई) थ्रेड द्वारा परिवर्तित वस्तुओं को WinForms नियंत्रण को बाध्य करने के लिए गतिशील प्रॉक्सी बनाना चाहता हूं। ऐसी प्रॉक्सी प्रॉपर्टी चेंजेड इवेंट को रोकती है और उचित सिंक्रनाइज़ेशन कॉन्टेक्स्ट का उपयोग करके इसे प्रेषित करती है।UI थ्रेड
इस तरह मैं नौकरी करने के लिए एक सहायक वर्ग का उपयोग कर सकता हूं, हर बार मैन्युअल रूप से सिंक्रनाइज़ेशन को लागू किए बिना (if (control.InvokeRequired) etc.
)।
क्या लिनफू, कैसल या इसी तरह की लाइब्रेरी का उपयोग करने का कोई तरीका है?
[संपादित करें]
डेटा स्रोत जरूरी एक सूची नहीं है। यह किसी भी व्यापार वस्तु, जैसे हो सकता है:
interface IConnection : INotifyPropertyChanged
{
ConnectionStatus Status { get; }
}
मैं एक आवरण है जो काम कर सकता है बना सकते हैं, और यह कुछ इस तरह दिखेगा:
public class ConnectionWrapper : IConnection
{
private readonly SynchronizationContext _ctx;
private readonly IConnection _actual;
public ConnectionWrapper(IConnection actual)
{
_ctx = SynchronizationContext.Current;
_actual= actual;
_actual.PropertyChanged +=
new PropertyChangedEventHandler(actual_PropertyChanged);
}
// we have to do 2 things:
// 1. wrap each property manually
// 2. handle the source event and fire it on the GUI thread
private void PropertyChanged(object sender, PropertyChangedEvArgs e)
{
// we will send the same event args to the GUI thread
_ctx.Send(delegate { this.PropertyChanged(sender, e); }, null);
}
public ConnectionStatus Status
{ get { return _instance.Status; } }
public event PropertyChangedEventHandler PropertyChanged;
}
(इस में कुछ त्रुटियों हो सकता है कोड, मैं इसे बना रहा हूं)
मैं क्या करना चाहता हूं कि गतिशील प्रॉक्सी (प्रतिबिंब.इमिट) इस के लिए एक लाइनर है, उदाहरण के लिए
IConnection syncConnection
= new SyncPropertyChangedProxy<IConnection>(actualConnection);
और मैं जानना चाहता था कि मौजूदा गतिशील प्रॉक्सी कार्यान्वयन का उपयोग करके ऐसा कुछ संभव था या नहीं।
एक और सामान्य प्रश्न होगा: एक गतिशील प्रॉक्सी बनाते समय किसी ईवेंट को कैसे रोकें? सभी कार्यान्वयन में इंटरसेप्टिंग (ओवरराइडिंग) गुणों को अच्छी तरह से समझाया गया है।
[EDIT2]
कारण (मुझे लगता है कि) मैं की जरूरत है एक प्रॉक्सी है कि स्टैक ट्रेस इस तरह दिखता है:
at PropertyManager.OnCurrentChanged(System.EventArgs e) at BindToObject.PropValueChanged(object sender, EventArgs e) at PropertyDescriptor.OnValueChanged(object component, EventArgs e) at ReflectPropertyDescriptor.OnValueChanged(object component, EventArgs e) at ReflectPropertyDescriptor.OnINotifyPropertyChanged(object component, PropertyChangedEventArgs e) at MyObject.OnPropertyChanged(string propertyName)
आप देख सकते हैं कि BindToObject.PropValueChanged
sender
उदाहरण पास नहीं PropertyManager
पर, और परावर्तक दिखाता है कि प्रेषक ऑब्जेक्ट को कहीं भी संदर्भित नहीं किया गया है। दूसरे शब्दों में, जब PropertyChanged
ईवेंट ट्रिगर किया जाता है, तो घटक मूल (बाध्य) डेटा स्रोत की संपत्ति तक पहुंचने के लिए प्रतिबिंब का उपयोग करेगा।
यदि मैंने अपनी ऑब्जेक्ट को केवल उस ईवेंट (जैसे Sam प्रस्तावित) श्रेणी में लपेट लिया है, तो ऐसे रैपर वर्ग में कोई भी गुण नहीं होगा जिसे प्रतिबिंब के माध्यम से एक्सेस किया जा सके।
'देखें ThreadedBindingList' - इसे यहाँ इतने पर दोहराया गया है (http://stackoverflow.com/questions/455766/how-do-you -correctly अद्यतन एक डेटाबाउंड-DataGridView-से-एक पृष्ठभूमि धागा)। –