2010-08-28 4 views
7

में डायनामिक यूआई जनरेशन मैं पुस्तकालय के लिए एक आवेदन तैयार कर रहा हूं। एक बड़े पैमाने पर पुस्तकालय नहीं, लेकिन एक बहुत ही छोटी पुस्तकालय जहां मेरा प्राथमिक कार्य केवल किताबों के बारे में जानकारी रखना है। लेकिन यह पुस्तकालय आवेदन किसी भी पेशेवर की निजी पुस्तकालय को अनुकूलित करने में सक्षम होना चाहिए। उदाहरण के लिए, एक वकील के लिए, पुस्तक (शीर्षक, लेखक, प्रकाशक इत्यादि) के बारे में मूलभूत जानकारी के अलावा, वहां अन्य विशेष फ़ील्ड जो किसी पुस्तक (केस नंबर, कोर्ट नंबर इत्यादि) से जुड़ी हो सकती हैं। एक डॉक्टर के पास एक किताब के लिए कुछ अन्य विशेष गुण हो सकते हैं। अन्य व्यवसायों के लिए भी चला जाता है।सी #

तो मैं एक SQL सर्वर सीई डेटाबेस का उपयोग करने जा रहा हूं और मुझे सामान्य विशेषताओं और मांग पर एक बुक टेबल होने की उम्मीद है, विशेष आवश्यकताओं के अनुरूप तालिका (अधिक कॉलम जोड़ें)।

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

क्या गतिशील जीयूआई पीढ़ी से निपटने के लिए कोई दृष्टिकोण है?

मैं पूरा कोड के लिए पूछ नहीं कर रहा हूँ (जो स्पष्ट रूप से मैं अभ्यस्त मिल), लेकिन अगर आप दृष्टिकोण का समर्थन करने के लिए किसी भी कोडिंग की क्या ज़रूरत है, यह :)

पोस्ट करने के लिए तरह पर्याप्त हो तो कृपया क्या मुझे पता होना चाहिए है पेशेवरों, विपक्ष, मृत सिरों, सावधानियों या चेतावनियों आदि के बारे में?

+0

क्या मंच आप के लिए विकसित कर रहे हैं? मोबाइल? वेब? डेस्कटॉप? – anonymous

+0

मैं डेस्कटॉप के लिए विकसित करने के लिए सी # का उपयोग कर रहा हूं। WinForms :) –

उत्तर

5

डाटा मॉडल पक्ष कि @devnull उठाया, तो आप एक कस्टम फ़ील्ड कार्यान्वयन का वर्णन कर रहे हैं और @devnull EAV मॉडल का वर्णन किया गया है पर।

वहाँ एक अच्छा stackoverflow लेख है कि एक आवेदन पत्र में कस्टम फ़ील्ड के लिए डिजाइन पैटर्न को शामिल किया गया है: तो क्या तुम सच में यूआई उत्तर नहीं दे सकता,

What are design patterns to support custom fields in an application?

डाटा मॉडल पसंद और यूआई पीढ़ी कसकर जुड़े हुए हैं पीढ़ी का सवाल जब तक आप अपने डेटा मॉडल/कस्टम फ़ील्ड पैटर्न पर निर्णय नहीं लेते। मेरी प्रारंभिक प्रतिक्रिया बदलती दृष्टिकोण पर @ देवनुल की तरह ही थी, लेकिन वास्तव में कोई अच्छा समाधान नहीं है।

यदि आपके पास सभी संभावित फ़ील्ड का सुपरसेट है और उपयोगकर्ता को उनके एप्लिकेशन डोमेन के लिए उचित सक्षम करने की अनुमति देता है तो आप बहुत जटिलता को कम कर सकते हैं। मैंने बहुत ही स्मार्ट लोगों के साथ एक एप्लिकेशन में कस्टम फ़ील्ड के कई कार्यान्वयन किए हैं और यह हमेशा कठिन होता है। यदि आप एप्लिकेशन डोमेन को पर्याप्त रूप से समझते हैं तो आप उबर-लचीले आर्किटेक्चर से दूर रह सकते हैं और खुद को बहुत दुख बचा सकते हैं।

ध्यान दें कि एक महत्वपूर्ण विचार यह है कि उन्हें कस्टम फ़ील्ड पर क्वेरी करने की आवश्यकता होगी या नहीं। यदि आपको सामान्य पूछताछ का समर्थन नहीं करना है तो यह बहुत आसान है। आप बस userdate1, usern, आदि slot और लेबल के लिए मेटाडेटा तालिका प्रदान करते हैं।

+0

दुर्भाग्यवश क्वेरी फ़ील्ड के लिए आवश्यक है। आईएमओ, कस्टम क्षेत्र के लिए अधिक उपयोग नहीं किया जाएगा यदि उपयोगकर्ता सही खोज नहीं कर सकता है? –

4

मुझे नहीं पता कि तालिका गतिशील रूप से एक अच्छा डिजाइन निर्णय है या नहीं। इसके बजाय आप एक लुकअप टेबल ले सकते हैं जिसमें आप विस्तार प्रकार परिभाषित कर सकते हैं, और एक पुस्तक विवरण तालिका जिसमें आप इन विवरणों को स्टोर करेंगे। फिर आप इन विवरणों को पुस्तक संपादन अनुभाग में डेटाग्रिड के रूप में प्रदर्शित कर सकते हैं जिसमें पंक्तियों के रूप में विस्तृत प्रकार हैं, प्रत्येक पंक्ति में एक स्तंभ होता है जिसमें आप मान संपादित करेंगे। बेशक, एक पुस्तक का विस्तार एक साधारण स्ट्रिंग मान से कुछ और हो सकता है लेकिन इसे आसानी से संभाला जा सकता है। आशा है कि मैं काफी स्पष्ट था :)

-------------   -----------------   ---------------- 
| Books |   | BooksDetail |   | DetailTypes | 
-------------   -----------------   ---------------- 
| ID (PK) | 1  n | ID (PK)  | 1  1 | ID (PK)  | 
| AuthorID | --------> | BookID  | -------> | Name   | 
| Title  |   | DetailID  |   | Description | 
| Year  |   | Value   |   ---------------- 
-------------   ----------------- 
+0

धन्यवाद devnull। यह एक बहुत अच्छा विचार है और मैं भी इसी तरह के साथ आया था। लेकिन समस्या यह है कि मैं केवल एक विशिष्ट डेटा प्रकार को स्टोर करने में सक्षम हो जाएगा। क्या आप यह समझाएंगे कि तालिका में बदलाव क्यों अच्छा डिजाइन निर्णय नहीं है? :) –

+0

क्योंकि उस तालिका के आधार पर सब कुछ उन परिवर्तनों को दर्शाने के लिए अद्यतन करने की आवश्यकता होगी। एक निश्चित और सुसंगत स्कीमा होने से डेटा स्टोर और एप्लिकेशन के बीच एक साफ अलगाव की अनुमति मिलती है। यदि आप एक वेबपैप लिखने की योजना बनाते हैं जो एक ही डेटाबेस के साथ काम करता है तो आपको डेटाबेस स्कीमा अपडेट को संभालने वाले कोड को डुप्लिकेट करना होगा। तालिका को गतिशील रूप से बदलने के लिए – devnull

+0

प्लस 1 एक खराब डिजाइन निर्णय –

3

बहुत सारे कोड जनरेशन टूल उपलब्ध हैं। उनमें से कुछ आसानी से उपयोग करने योग्य जीयूआई के साथ कोड उत्पन्न करता है।

MyGeneration

CodeNGen

CodeSmith

IgnyteDataLayerGen

NetGenerationCodeGen

OxyGen Code Generator

.NetTiers

CodeThatBuilder

CslaGenerator

CodeBreeze

वैकल्पिक रूप से निम्नलिखित कोड अपने जीवन और अधिक आसान बनाने के कर सकते हैं।

public partial class BaseForm : Form 
    { 
     ///////////Event Mechanism/////////// 
     protected internal event ItemStateChanged ItemStateChangeEvent; 
     protected internal void OnItemStateChanged() 
     { 
      if (ItemStateChangeEvent != null) 
      { 
       ItemStateChangeEvent(); 
      } 
     } 
     ///////////Event Mechanism/////////// 

     protected internal Label ErrorMessageTextBox 
     { 
      get { return this.errorMessageTextBox; } 
      set { this.errorMessageTextBox = value; } 
     } 

     protected internal ToolStripStatusLabel TotalToolStripStatusLabel 
     { 
      get { return this.totalToolStripStatusLabel; } 
      set { this.totalToolStripStatusLabel = value; } 
     } 

     protected internal FormViewMode FormViewMode { get; set; } 

     public BaseForm() 
     { 
      InitializeComponent(); 
     } 
    } 

और संग्रह के लिए एक सामान्य आधार रूप:

public partial class CollectionBaseForm : BaseForm 
    { 
     protected internal ToolStripMenuItem ReportMenu { get { return this.reportsToolStripMenuItem; } set { this.reportsToolStripMenuItem = value; } } 
     protected internal DataGridView DataGridView { get {return this.dataGridView1 ;} set {dataGridView1 = value ;} } 
     protected internal Button SearchButton { get { return btnSearch; } set { btnSearch = value; } } 
     protected internal Button AddNewButton { get { return btnAddNew; } set { btnAddNew = value; } } 
     protected internal Button EditButton { get { return btnEdit; } set { btnEdit = value; } } 
     protected internal Button DeleteButton { get { return btnDelete; } set { btnDelete = value; } } 
     protected internal Button PickButton { get { return btnPick; } set { btnPick = value; } } 

     private FormViewMode _formViewMode; 
     public FormViewMode FormViewMode 
     { 
      get 
      { 
       return _formViewMode; 
      } 
      set 
      { 
       _formViewMode = value; 

       EnableDisableAppropriateButtons(_formViewMode); 
      } 
     } 

     private void EnableDisableAppropriateButtons(FormViewMode FormViewMode) 
     { 
      if (FormViewMode == FormViewMode.Collection) 
      { 
       AddNewButton.Enabled = true; 
       EditButton.Enabled = true; 
       DeleteButton.Enabled = true; 
       PickButton.Enabled = false; 
      } 
      else if (FormViewMode == FormViewMode.Picker) 
      { 
       AddNewButton.Enabled = false; 
       EditButton.Enabled = false; 
       DeleteButton.Enabled = false; 
       PickButton.Enabled = true; 
      } 
     } 

     public CollectionBaseForm() 
     { 
      InitializeComponent(); 

      this.MaximumSize = this.MinimumSize = this.Size; 

      this.FormViewMode = FormViewMode.Collection; 
     } 

     private void closeToolStripMenuItem_Click(object sender, EventArgs e) 
     { 
      this.Close(); 
     } 

     protected override void OnResize(EventArgs e) 
     { 
      base.OnResize(e); 
     }    
    } 

फिर अपने रूपों के सभी एक ही सामान्य दिखता होगा

आप इस तरह की संस्थाओं के लिए एक सामान्य आधार रूप हो सकते हैं:

alt text