2010-08-09 19 views
8

मैं एक्सटेंशन विधियों का उपयोग करके मजबूत टाइप किए गए विंडोज फॉर्म डेटाबेस में देख रहा हूं। मैं नीचे के रूप में Xavier से दूर नीचे दी गई सहायता मिल गया है:मजबूत टाइप किए गए विंडोज फॉर्म डेटाबेस

txtBoundInt.DataBindings.Add<Contact> 
    (bindingSource, tb => tb.Text, contact => contact.Id); 

या इस:

cboBoundSelectedItem.DataBindings.Add 
      <Contact, ComboBox> 
      (bindingSource, cbo => cbo.SelectedItem, con => con.ContactType) 

वहाँ हो रहा है

using System; 
using System.Linq.Expressions; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public static Binding Add<T> 
     (this ControlBindingsCollection dataBindings, 
      object dataSource, 
      Expression<Func<Control, object>> controlExpression, 
      Expression<Func<T, object>> objectExpression) 
    { 
     return Add(dataBindings, dataSource, controlExpression, objectExpression, false); 
    } 

    public static Binding Add<T> 
     (this ControlBindingsCollection dataBindings, 
      object dataSource, 
      Expression<Func<Control, object>> controlExpression, 
      Expression<Func<T, object>> objectExpression, 
      bool formattingEnabled) 
    { 
     string controlPropertyName = ProcessExpression(controlExpression.Body); 
     string bindingTargetName = ProcessExpression(objectExpression.Body); 

     return dataBindings 
      .Add(controlPropertyName, dataSource, bindingTargetName, formattingEnabled); 
    } 

    public static Binding Add<T, K> 
     (this ControlBindingsCollection dataBindings, 
      object dataSource, 
      Expression<Func<K, object>> controlExpression, 
      Expression<Func<T, object>> objectExpression) 
    { 
     return Add(dataBindings, dataSource, controlExpression, objectExpression, false); 
    } 

    public static Binding Add<T, K> 
     (this ControlBindingsCollection dataBindings, 
      object dataSource, 
      Expression<Func<K, object>> controlExpression, 
      Expression<Func<T, object>> objectExpression, 
      bool formattingEnabled 
     ) 
    { 
     string controlPropertyName = ProcessExpression(controlExpression.Body); 
     string bindingTargetName = ProcessExpression(objectExpression.Body); 

     return dataBindings.Add(controlPropertyName, dataSource, bindingTargetName, formattingEnabled); 
    } 

    private static string ProcessExpression(Expression expression) 
    { 
     string propertyName; 
     if (expression is MemberExpression) 
     { 
      propertyName = ((MemberExpression) (expression)).Member.Name; 
     } 
     else if (expression is UnaryExpression) 
     { 
      propertyName = ((MemberExpression) ((UnaryExpression) (expression)).Operand).Member.Name; 
     } 
     else 
     { 
      throw new InvalidOperationException(
       "Unknown expression type error in DataBindingsExtensionMethods.Add<T, K>"); 
     } 
     return propertyName; 
    } 
} 

अब मैं इस तरह एक DataBinding सेट कर सकते हैं यद्यपि अभिव्यक्तियों का बहुत सारे कास्टिंग चल रहा है। क्या कोई बेहतर तरीका है?


संपादित करें: मैं एक बेहतर तरीका खोजने के किया था, लेकिन मुझे लगता है कि जवाब देने के लिए इस सवाल का बदलने के लिए मुसीबत में मिला - यह reproduced below @Carl_G से है।

+0

कृपया अपने प्रश्न को उत्तर में संशोधित न करें। यदि आपको कोई समाधान मिला है, तो इसे उत्तर अनुभाग में जाना होगा। एक समाधान के लिए Google लिंक को तेजी से ब्राउज़ करने का प्रयास करने वाले व्यक्ति के लिए, "ठीक है, मुझे एक समाधान मिला" पढ़ने के लिए बहुत ही विचलित है, यह जानने के बिना कि आपका प्रश्न क्या था, या यह मूल्यांकन करने में सक्षम है कि यह विज़िटर की समस्या पर लागू है या नहीं। –

+0

ओह ठीक है, नियमों से खेलना है .. – stuartd

+0

यह ध्यान दिया जाना चाहिए कि सी # 6 में नया नाम() फ़ंक्शन का उपयोग स्ट्रिंग का उपयोग करने से बचने के लिए भी किया जा सकता है। https://msdn.microsoft.com/en-us/library/dn986596.aspx –

उत्तर

6

वापसी प्रकार को ऑब्जेक्ट में सेट करने के बारे में क्या?

public static Binding Add<T> 
    (this ControlBindingsCollection dataBindings, object dataSource, 
    Expression<Func<Control, object>> controlLambda, 
    Expression<Func<T, object>> objectLambda) { 
    string controlPropertyName = 
      ((MemberExpression)(controlLambda.Body)).Member.Name; 
    string bindingTargetName = 
      ((MemberExpression)(objectLambda.Body)).Member.Name; 

    return dataBindings.Add 
     (controlPropertyName, dataSource, bindingTargetName); 
} 
+0

धन्यवाद: यह संकलित करता है, लेकिन इस रनटाइम त्रुटि उत्पन्न करता है: 'System.Linq.Expressions.UnaryExpression' प्रकार के ऑब्जेक्ट को 'सिस्टम' टाइप करने में असमर्थ .Linq.Expressions.MemberExpression '। – stuartd

+0

हम्म। मैं ऑब्जेक्ट लैम्ब्डा को एक यूनरीएक्सप्रेस पर डाल सकता हूं, लेकिन मैं नहीं देख सकता कि यूनरीएक्सप्रेस से संपत्ति का नाम कैसे प्राप्त करें .. (नियंत्रण लैम्ब्डा अभी भी एक सदस्य एक्सप्रेशन है) – stuartd

+0

आपकी मदद के लिए बहुत धन्यवाद, यह अब नाखुश है। – stuartd

2

मैं कुछ महीनों के लिए स्टुअर्ट द्वारा पोस्ट किए गए कोड का उपयोग कर रहा हूं। मैं डेटा बाइंडिंग परिदृश्यों के बाकी मैच के लिए कुछ और भार के जोड़ने है कि आप उपयोग कर सकते हैं (मैं तो बस इसे यहाँ पोस्ट कर रहा हूँ दूसरों करना और भी आसान समय यह बहुत ही उपयोगी काम कर बात हो रही है करने के लिए के लिए)

public static class ControlExtensions { 

    /// <summary>Databinding with strongly typed object names</summary> 
    /// <param name="control">The Control you are binding to</param> 
    /// <param name="controlProperty">The property on the control you are binding to</param> 
    /// <param name="dataSource">The object you are binding to</param> 
    /// <param name="dataSourceProperty">The property on the object you are binding to</param> 
    public static Binding Bind<TControl, TDataSourceItem>(this TControl control, Expression<Func<TControl, object>> controlProperty, object dataSource, Expression<Func<TDataSourceItem, object>> dataSourceProperty) 
    where TControl :Control { 
     return control.DataBindings.Add(PropertyName.For(controlProperty), dataSource, PropertyName.For(dataSourceProperty)); 
    } 
    public static Binding Bind<TControl, TDataSourceItem>(this TControl control, Expression<Func<TControl, object>> controlProperty, object dataSource, Expression<Func<TDataSourceItem, object>> dataSourceProperty, bool formattingEnabled = false) 
    where TControl :Control { 
     return control.DataBindings.Add(PropertyName.For(controlProperty), dataSource, PropertyName.For(dataSourceProperty), formattingEnabled); 
    } 
    public static Binding Bind<TControl, TDataSourceItem>(this TControl control, Expression<Func<TControl, object>> controlProperty, object dataSource, Expression<Func<TDataSourceItem, object>> dataSourceProperty, bool formattingEnabled, DataSourceUpdateMode updateMode) 
    where TControl :Control { 
     return control.DataBindings.Add(PropertyName.For(controlProperty), dataSource, PropertyName.For(dataSourceProperty), formattingEnabled, updateMode); 
    } 
    public static Binding Bind<TControl, TDataSourceItem>(this TControl control, Expression<Func<TControl, object>> controlProperty, object dataSource, Expression<Func<TDataSourceItem, object>> dataSourceProperty, bool formattingEnabled, DataSourceUpdateMode updateMode, object nullValue) 
    where TControl :Control { 
     return control.DataBindings.Add(PropertyName.For(controlProperty), dataSource, PropertyName.For(dataSourceProperty), formattingEnabled, updateMode, nullValue); 
    } 
    public static Binding Bind<TControl, TDataSourceItem>(this TControl control, Expression<Func<TControl, object>> controlProperty, object dataSource, Expression<Func<TDataSourceItem, object>> dataSourceProperty, bool formattingEnabled, DataSourceUpdateMode updateMode, object nullValue, string formatString) 
    where TControl :Control { 
     return control.DataBindings.Add(PropertyName.For(controlProperty), dataSource, PropertyName.For(dataSourceProperty), formattingEnabled, updateMode, nullValue, formatString); 
    } 
    public static Binding Bind<TControl, TDataSourceItem>(this TControl control, Expression<Func<TControl, object>> controlProperty, object dataSource, Expression<Func<TDataSourceItem, object>> dataSourceProperty, bool formattingEnabled, DataSourceUpdateMode updateMode, object nullValue, string formatString, IFormatProvider formatInfo) 
    where TControl :Control { 
     return control.DataBindings.Add(PropertyName.For(controlProperty), dataSource, PropertyName.For(dataSourceProperty), formattingEnabled, updateMode, nullValue, formatString, formatInfo); 
    } 

    public static class PropertyName { 
     public static string For<T>(Expression<Func<T, object>> property) { 
      var member = property.Body as MemberExpression; 
      if(null == member) { 
       var unary = property.Body as UnaryExpression; 
       if(null != unary) member = unary.Operand as MemberExpression; 
      } 
      return null != member ? member.Member.Name : string.Empty; 
     } 
    } 

} 
+2

यह कोड अच्छी तरह से काम किया। हालांकि इसे एक छोटे से फिक्स की जरूरत है। 'नियंत्रण' को बाधित करने के बजाय, इसे 'IBindableComponent' से बाध्य किया जाना चाहिए। यह उचित इंटरफ़ेस है जिसमें 'डेटा बाइंडिंग्स' संपत्ति है। – craigtadlock

4
किया

जैसा कि प्रश्न को केवल एक उत्तर शामिल करने के लिए संपादित किया गया है, मैं यहां उस उत्तर को शामिल कर रहा हूं। लेखक को शायद the original question अकेले छोड़ देना चाहिए था और अपने प्रश्न का उत्तर पोस्ट करना चाहिए था। लेकिन यह एक बहुत अच्छा समाधान प्रतीत होता है।


संपादित करें: मैं इस समाधान मैंने पाया अंततः in Google's cache (यह author's site से हटा दिया गया है) के रूप में यह केवल एक ही प्रकार विनिर्देश की जरूरत है पसंद करते हैं। मुझे नहीं पता कि मूल लेखक ने इसे क्यों हटा दिया।

// Desired call syntax: 
nameTextBox.Bind(t => t.Text, aBindingSource, (Customer c) => c.FirstName); 

// Binds the Text property on nameTextBox to the FirstName property 
// of the current Customer in aBindingSource, no string literals required. 

// Implementation. 

public static class ControlExtensions 
{ 
    public static Binding Bind<TControl, TDataSourceItem> 
     (this TControl control, 
     Expression<Func<TControl, object>> controlProperty, 
     object dataSource, 
     Expression<Func<TDataSourceItem, object>> dataSourceProperty) 
     where TControl: Control 
    { 
     return control.DataBindings.Add 
      (PropertyName.For(controlProperty), 
       dataSource, 
       PropertyName.For(dataSourceProperty)); 
    } 
} 

public static class PropertyName 
{ 
    public static string For<T>(Expression<Func<T, object>> property) 
    { 
     var member = property.Body as MemberExpression; 
     if (null == member) 
     { 
      var unary = property.Body as UnaryExpression; 
      if (null != unary) member = unary.Operand as MemberExpression; 
     } 
     return null != member ? member.Member.Name : string.Empty; 
    } 
} 
+3

SO में एक प्रश्न-उत्तर प्रारूप है।यह इस तरह से डिज़ाइन किया गया है ताकि एक ही समस्या/प्रश्न वाले व्यक्ति उनके पास समस्या/प्रश्नों की खोज कर सकें, और फिर समाधान से समाधान या सुझाव दे सकें। मैं अलग-अलग स्टाइलिस्ट प्राथमिकताओं वाले विभिन्न उपयोगकर्ताओं के लिए खुला हूं, लेकिन मैं आपके मूल प्रश्न को पूरी तरह से हटाकर असहमत हूं। जिस जवाब के साथ आपने इसे बदल दिया है, उसमें अब सभी संदर्भों का अभाव है जो प्रश्न इसके लिए प्रदान करता है। ऐसा करने से न केवल एसओ के डिजाइन के खिलाफ जा रहा है, बल्कि यह दूसरों के लिए यहां मौजूद जानकारी से लाभ उठाने में भी मुश्किल बनाता है। –

+0

नहीं, यह सिर्फ सही स्थान पर एक उत्तर क्या था। तो अगर किसी ने फैसला किया "ठीक है, मुझे लगता है कि मैं समझता हूं कि यह समस्या क्या है, अब मैं जवाब देखने के लिए स्कैन करने जा रहा हूं कि क्या कोई अच्छा है या नहीं" वे आपके द्वारा शामिल किए गए अच्छे जवाब को देख सकते थे। –

+0

क्या आपने देखा कि मैंने शुरुआत में अपना मूल प्रश्न वापस रखा था और फिर आपका जवाब इसके बाद था? (और अब केवल उत्तर ही रहता है जैसा कि आपने पहले किया था।) मैंने सोचा कि शायद आपने इसे वापस कर दिया है, लेकिन शायद एक व्यवस्थापक ने इसे वापस कर दिया। मुझे नहीं पता, मैं बस मदद करने की कोशिश कर रहा था। –

संबंधित मुद्दे