2009-01-11 7 views
6

समस्या 1:सी क्लास और ऑपरेटर के लिए डिफ़ॉल्ट संपत्ति नियत # =

मैं एक सरल WinForms अनुप्रयोग है और मैं एक पाठ बॉक्स के लिए मेरे Person.Name संपत्ति DataBind करना चाहते हैं। नाम स्ट्रिंगफिल्ड प्रकार का है। मैंने मूल रूप से नाम संपत्ति को स्ट्रिंग के रूप में परिभाषित किया। डेटा बाइंडिंग स्ट्रिंग जैसे मूल्य प्रकारों पर बहुत बढ़िया काम करती है। मुझे StringField.Value प्रॉपर्टी स्ट्रिंगफ़िल्ल्ड की डिफ़ॉल्ट प्रॉपर्टी चाहिए। मैं "FieldApp.StringField" टेक्स्ट के बजाय टेक्स्टबॉक्स में StringField.Value का मान देखना चाहता हूं।

समस्या 2:

मैं ऑपरेटर का उपयोग कर एक StringField के लिए एक स्ट्रिंग आवंटित करने के लिए = सक्षम होने के लिए करना चाहते हैं। इस असाइनमेंट के परिणामस्वरूप स्ट्रिंगफ़िल्ल्ड होगा। वैल्यू सदस्य सेट किया जा रहा है।

क्या यह पूरा किया जा सकता है?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace FieldApp 
{ 
    public class StringField 
    { 
     public string Value { get; set; }  
    } 

    public class Person 
    { 

     //private String _Name; 
     //public String Name 
     //{ 
     // get { return _Name; } 
     // set { _Name = value; } 
     //} 

     //public Person(string name) 
     //{ 
     // Name = name; 
     //} 

     private StringField _Name; 
     public StringField Name 
     { 
      get { return _Name; } 
      set { _Name = value; } 
     } 

     public Person(string name) 
     { 
      Name = new StringField(); 
      Name.Value = name; 
     } 
    } 

    public partial class FieldAppForm : Form 
    { 
     Person person = new Person("steve"); 

     public FieldAppForm() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      //our form contains a button1 and textBox1 

      //this compiles 
      person.Name.Value = "steve"; 

      //this does not. Is there anyway to accomplish this? 
      person.Name = "steve"; 

      //steve appears in the textbox 
      textBox1.DataBindings.Add("Text", person, "Name.Value"); 

      //FieldApp.StringField appears in the textbox 
      textBox1.DataBindings.Add("Text", person, "Name"); 
     } 
    } 
} 

उत्तर

10

आप एक implisit ऑपरेटर अधिभार बना सकते हैं। फिर आप स्ट्रिंगफील्ड को इस तरह तारों से बना सकते हैं:

StringField field = "value of new object"; 
string value=(string)field; 

पता है कि यह एक नई स्ट्रिंगफ़िल्ड ऑब्जेक्ट बनाता है। मैं आपको यह करने के लिए दृढ़ता से सलाह नहीं दूंगा।

[System.Diagnostics.DebuggerDisplay("{Value}")] 
public class StringField 
{ 
    public string Value { get; set; } 
    public static implicit operator StringField(string s) 
    { 
     return new StringField { Value = s }; 
    } 

    public static explicit operator string(StringField f) 
    { 
     return f.Value; 
    } 
    public override string ToString() 
    { 
     return Value; 
    } 
} 
0

आप नाम संपत्ति पर नाम संपत्ति का मानचित्रण करके स्ट्रिंगफ़ील्ड को हरा सकते हैं। अपनी कक्षा में आंतरिक रूप से वैल्यू फ़ील्ड।

तो आप इस तरह का नाम संपत्ति को परिभाषित कर सकते हैं:

string Name 
{ 
    get { return _name.Value; } 
    set { _name.Value = value; } 
} 

यहाँ नाम_ अपने StringField चर रहा है।

0

असाइनमेंट ऑपरेटर को सी # में ओवरराइड नहीं किया जा सकता है। आप फिर भी आप के लिए जैसे रूपांतरण करने के लिए एक संपत्ति है और बेनकाब है कि एक वर्ग

2

पुन डेटा-बाइंडिंग, कुछ बाध्यकारी लक्ष्य (PropertyGrid, DataGridView, आदि) के लिए, आप एक TypeConverter के साथ ऐसा कर सकते हैं (हो सकता है निचे देखो)। दुर्भाग्य से, इस TextBox के साथ काम करने नहीं लगता है, तो मुझे लगता है आपका सबसे अच्छा विकल्प के लिए बस एक शिम संपत्ति (के रूप में पहले से ही सुझाव दिया) जोड़ने के लिए है:

string NameString 
{ 
    get { return Name.Value; } 
    set { Name.Value = value; } // or new blah... 
} 

(NameString करने और बाँध)

में अतीत में, मैंने कस्टम PropertyDescriptor कार्यान्वयन का उपयोग साइड-चरण के लिए किया है, लेकिन इसके लिए केवल इसके लायक नहीं है।

वैसे भी, एक TypeConverter उदाहरण (PropertyGrid और DataGridView साथ काम करता है):

[TypeConverter(typeof(StringFieldConverter))] 
public class StringField 
{ 
    public StringField() : this("") { } 
    public StringField(string value) { Value = value; } 
    public string Value { get; private set; } 
} 

class StringFieldConverter : TypeConverter 
{ 
    public override bool CanConvertFrom(
     ITypeDescriptorContext context, Type sourceType) 
    { 
     return sourceType == typeof(string) 
      || base.CanConvertFrom(context, sourceType); 
    } 
    public override object ConvertFrom(
     ITypeDescriptorContext context, 
     System.Globalization.CultureInfo culture, 
     object value) 
    { 
     string s = value as string; 
     if (s != null) return new StringField(s); 
     return base.ConvertFrom(context, culture, value); 
    } 
    public override bool CanConvertTo(
     ITypeDescriptorContext context, Type destinationType) 
    { 
     return destinationType == typeof(string) 
      || base.CanConvertTo(context, destinationType); 
    } 
    public override object ConvertTo(
     ITypeDescriptorContext context, 
     System.Globalization.CultureInfo culture, 
     object value, Type destinationType) 
    { 
     if (destinationType == typeof(string) && value != null 
      && value is StringField) 
     { 
      return ((StringField)value).Value; 
     } 
     return base.ConvertTo(context, culture, value, destinationType); 
    } 
} 
1

आप एक रूपांतरण ऑपरेटर प्रदान करके काम को लागू कर सकते हैं। अपनी कक्षा की प्रकृति को देखते हुए, आपको ऑब्जेक्ट विधियों को ओवरराइड करना चाहिए:

public class StringField { 
    public string Value { get; set; } 
    public static implicit operator StringField(string value) { 
    StringField sf = new StringField(); 
    sf.Value = value; 
    return sf; 
    } 
    public override string ToString() { 
    return Value; 
    } 
    public override bool Equals(object obj) { 
    if (obj == null || !(obj is StringField)) return false; 
    return 0 == string.Compare(Value, (obj as StringField).Value); 
    } 
    public override int GetHashCode() { 
    return Value.GetHashCode(); 
    } 
} 
संबंधित मुद्दे