विंडोज फॉर्म में किसी अन्य रूप पर नियंत्रण तक पहुंचने का सबसे अच्छा तरीका?

सबसे पहले, यह Windows फॉर्म का उपयोग कर डेस्कटॉप एप्लिकेशन के बारे में एक प्रश्न है, न कि एक ASP.NET </ए> सवाल।

मुझे अन्य रूपों पर नियंत्रण के साथ बातचीत करने की जरूरत है। मैं उपयोग करके नियंत्रणों तक पहुंचने की कोशिश कर रहा हूं, उदाहरण के लिए, निम्नलिखित ...

otherForm.Controls["nameOfControl"].Visible = false;

यह जिस तरह से मैं उम्मीद करता हूं काम नहीं करता है। मैं मुख्य से फेंक दिया गया अपवाद समाप्त करता हूं। हालांकि, अगर मैं निजी के बजाय नियंत्रण public करता हूं, तो मैं उन्हें सीधे एक्सेस कर सकता हूं, इसलिए ...

otherForm.nameOfControl.Visible = false;

लेकिन क्या यह करने का सबसे अच्छा तरीका है? नियंत्रण "कोड> सार्वजनिक को दूसरे रूप में" सर्वोत्तम अभ्यास "माना जाता है? क्या किसी अन्य रूप पर नियंत्रण तक पहुंचने का एक "बेहतर" तरीका है?

आगे स्पष्टीकरण:

यह वास्तव में मेरे द्वारा पूछे गए किसी अन्य प्रश्न का अनुवर्ती प्रकार है,

पेड़-दृश्य वरीयता संवाद बनाने के लिए सर्वोत्तम विधि? सी #? में इंटरफ़ेस का प्रकार। मुझे जो जवाब मिला वह बहुत अच्छा था और यूआई को सीधे और समय-समय पर डिजाइन और समय के साथ काम करने में आसान रखने के मामले में कई संगठनात्मक समस्याएं हल हुईं। हालांकि, यह इंटरफ़ेस के अन्य पहलुओं को आसानी से नियंत्रित करने के लिए एक निगलने वाला मुद्दा सामने आया।

असल में, मेरे पास एक मूल रूप है जो रूट फॉर्म पर पैनल में बैठे कई अन्य रूपों को तुरंत चालू करता है। इसलिए, उदाहरण के लिए, उन उप-रूपों में से एक पर एक रेडियो बटन को मुख्य, मूल रूप पर स्थिति पट्टी आइकन की स्थिति को बदलने की आवश्यकता हो सकती है। उस स्थिति में, मुझे पैरेंट (रूट) फॉर्म की स्थिति पट्टी में नियंत्रण से बात करने के लिए उप-फॉर्म की आवश्यकता है। (मुझे आशा है कि यह समझ में आता है, "पहले पर कौन है" जिस तरह से।)

0
ro fr bn
क्या आप इन नियंत्रणों को बाहरी थ्रेड से बाहरी रूप से एक्सेस कर रहे हैं?
जोड़ा लेखक Tanerax, स्रोत
सुनिश्चित करें कि आप इसे अपनी कक्षा में डाल दें जो कि कन्स्ट्रक्टर में एक फॉर्म लेता है। इसे IDISposable इंटरफ़ेस को कार्यान्वित करने और समाप्त होने पर संपत्ति का निपटान करने की आवश्यकता है। इसे संदर्भ ट्रैकिंग का उपयोग करने की आवश्यकता है (एक पूर्णांक को बढ़ाना/घटाना, इसलिए इसे बार-बार कॉल करना इससे समस्याएं नहीं आतीं) और केवल 0 से 1 तक होने पर नियंत्रण छिपाने की आवश्यकता होती है और जब यह 1 से 0 तक जाती है तो केवल उन्हें फिर से दिखाती है।
जोड़ा लेखक TamusJRoyce, स्रोत

14 उत्तर

नियंत्रण को सार्वजनिक करने के बजाय, आप ऐसी संपत्ति बना सकते हैं जो इसकी दृश्यता को नियंत्रित करे:

public bool ControlIsVisible
{
     get { return control.Visible; }
     set { control.Visible = value; }
}

यह उस नियंत्रण के लिए एक उचित एक्सेसर बनाता है जो नियंत्रण के पूरे सेट का खुलासा नहीं करेगा।

0
जोड़ा

मैं व्यक्तिगत रूप से नहीं ऐसा करने की अनुशंसा करता हूं ... यदि यह किसी प्रकार की कार्रवाई का जवाब दे रहा है और इसे अपनी उपस्थिति बदलने की जरूरत है, तो मैं एक घटना को बढ़ाने और इसे स्वयं को हल करने की इच्छा रखूंगा ...

रूपों के बीच इस तरह के युग्मन हमेशा मुझे परेशान करता है। मैं हमेशा यूआई को प्रकाश के रूप में और स्वतंत्र जितना संभव हो रखने की कोशिश करता हूं ..

आशा है कि ये आपकी मदद करेगा। शायद आप परिदृश्य पर विस्तार कर सकते हैं अगर नहीं?

0
जोड़ा
कभी-कभी युग्मन ठीक है ... प्रोग्रामर निर्णय लेने में सक्षम होना चाहिए। यही कारण है कि संरक्षित पहुंच मूर्खतापूर्ण है।
जोड़ा लेखक eat_a_lemon, स्रोत

@ लार्स, फॉर्म संदर्भों के चारों ओर गुज़रने पर अच्छी कॉल, इसे स्वयं भी देखा। बुरा। उन्हें कभी भी बीएलएल परत पर उन्हें पास नहीं देखा! यह भी समझ में नहीं आता है! इससे प्रदर्शन पर गंभीरता से असर पड़ सकता है? यदि बीएलएल में कहीं भी संदर्भ रखा गया था, तो फॉर्म स्मृति में सही रहेगा?

तुम मेरी सहानुभूति रखते हो! ;)


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

0
जोड़ा

पहला कोर्स नहीं कर रहा है। किसी फॉर्म पर नियंत्रण निजी होते हैं, केवल उस फ़ॉर्म के लिए डिज़ाइन द्वारा दिखाई देते हैं।

इसे सभी सार्वजनिक बनाने के लिए भी सबसे अच्छा तरीका नहीं है।

अगर मैं बाहरी दुनिया में कुछ भी बेनकाब करना चाहता हूं (जिसका अर्थ एक और रूप भी हो सकता है), तो मैं इसके लिए एक सार्वजनिक संपत्ति बना सकता हूं।

public Boolean nameOfControlVisible
{
    get { return this.nameOfControl.Visible; }
    set { this.nameOfControl.Visible = value; }
}

आप इस सार्वजनिक संपत्ति का उपयोग नियंत्रण को छिपाने या दिखाने के लिए या मौजूदा दृश्यता संपत्ति को नियंत्रित करने के लिए कर सकते हैं:

otherForm.nameOfControlVisible = true;

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

public ControlType nameOfControlP
{
    get { return this.nameOfControl; }
    set { this.nameOfControl = value; }
}
0
जोड़ा

अतिरिक्त विवरण पढ़ने के बाद, मैं robcthegeek : एक ईवेंट उठाएं। एक कस्टम EventArgs बनाएँ और इसके माध्यम से निरंतर पैरामीटर पास करें।

0
जोड़ा

मैं इसे मूल रूप में संभाल दूंगा। आप किसी अन्य फॉर्म को सूचित कर सकते हैं जिसे इसे किसी ईवेंट के माध्यम से स्वयं संशोधित करने की आवश्यकता है।

0
जोड़ा

क्या आपके बच्चे के रूपों को वास्तव में फॉर्म बनने की ज़रूरत है? क्या वे इसके बजाय उपयोगकर्ता नियंत्रण हो सकते हैं? इस तरह, वे मुख्य रूप से संभालने के लिए मुख्य रूप से घटनाओं को बढ़ा सकते हैं और आप अपने तर्क को एक वर्ग में बेहतर ढंग से समाहित कर सकते हैं (कम से कम, तार्किक रूप से, वे पहले से ही सभी कक्षाओं के बाद हैं)।

@ लार्स: आप यहाँ हैं। यह कुछ ऐसा था जो मैंने अपने शुरुआती दिनों में किया था और इसे तब से नहीं करना पड़ा था, यही कारण है कि मैंने पहली बार एक घटना को बढ़ाने का सुझाव दिया था, लेकिन मेरी दूसरी विधि वास्तव में encapsulation के किसी भी समानता को तोड़ देगा।

@Rob: हाँ, सही के बारे में लगता है :)। 0/2 इस पर ...

0
जोड़ा

यदि आप अधिक जटिल नियंत्रण/मॉड्यूल/घटक बना रहे हैं तो आपको केवल एक दृश्य की सामग्री को किसी अन्य से एक्सेस करना चाहिए। अन्यथा, आपको मानक मॉडल-व्यू-कंट्रोलर आर्किटेक्चर के माध्यम से ऐसा करना चाहिए: आपको उन नियंत्रणों की सक्षम स्थिति को कनेक्ट करना चाहिए जिन्हें आप कुछ मॉडल-स्तरीय भविष्यवाणी के बारे में देखते हैं जो सही जानकारी प्रदान करते हैं।

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

इसका परिणाम प्रेजेंटेशन लॉजिक से बिजनेस लॉजिक के एक क्लीनर अलगाव में होता है, जिससे दोनों स्वतंत्र रूप से विकसित हो सकते हैं? आपको कई बैक-एंड के साथ एक फ्रंट-एंड बनाने या आसानी से एक सिंगल बैक-एंड के साथ कई फ्रंट-सिरों को बनाने देता है।

यह यूनिट और स्वीकृति परीक्षण लिखने के लिए बहुत आसान होगा, क्योंकि आप " विश्वास करें लेकिन सत्यापित करें " ऐसा करने में पैटर्न:

  1. आप परीक्षणों का एक सेट लिख सकते हैं जो आपके मॉडल ऑब्जेक्ट्स को विभिन्न तरीकों से स्थापित करता है और जांचता है कि "समझने योग्य" भविष्यवाणी उचित परिणाम देता है।

  2. आप उस चेक का एक अलग सेट लिख सकते हैं कि आपका सेव बटन एक उचित फैशन में "savable" predicate (जो भी आपके ढांचे के लिए है, मैक ओएस एक्स पर कोको में) से जुड़ा हुआ है या नहीं बाध्यकारी के माध्यम से)।

जब तक परीक्षण के दोनों सेट गुजर रहे हैं, तो आप भरोसा कर सकते हैं कि आपका यूजर इंटरफेस जिस तरह से आप चाहते हैं उस पर काम करेगा।

0
जोड़ा

मैं इसके लिए घटनाओं का उपयोग करने के साथ सहमत हूं। चूंकि मुझे संदेह है कि आप एक एमडीआई-एप्लिकेशन बना रहे हैं (चूंकि आप कई बच्चे रूप बनाते हैं) और विंडोज़ गतिशील रूप से बनाता है और शायद यह नहीं पता कि घटनाओं से सदस्यता समाप्त करने के लिए, मैं अनुशंसा करता हूं कि आप कमजोर ईवेंट पैटर्न । हां, यह केवल फ्रेमवर्क 3.0 और 3.5 के लिए उपलब्ध है लेकिन कुछ समान कमजोर संदर्भों के साथ काफी आसान कार्यान्वित किया जा सकता है।

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

public static Control FindControl(Form form, string name)
{
    foreach (Control control in form.Controls)
    {
        Control result = FindControl(form, control, name);

        if (result != null)
            return result;
    }

    return null;
}

private static Control FindControl(Form form, Control control, string name)
{
    if (control.Name == name) {
        return control;
    }

    foreach (Control subControl in control.Controls)
    {
        Control result = FindControl(form, subControl, name);

        if (result != null)
            return result;
    }

    return null;
}
0
जोड़ा

यह प्रस्तुति को डेटा मॉडल से अलग करने के लिए एक प्रमुख उम्मीदवार की तरह दिखता है। इस मामले में, आपकी वरीयताओं को एक अलग वर्ग में संग्रहीत किया जाना चाहिए जो किसी विशेष संपत्ति में परिवर्तन होने पर ईवेंट अपडेट को सक्रिय करता है (INOTifyProperty में देखें, यदि आपकी गुण एक अलग सेट हैं, या एक ईवेंट में यदि वे अधिक मुक्त-फॉर्म टेक्स्ट-आधारित कुंजी हैं )।

अपने पेड़ दृश्य में, आप अपने वरीयता मॉडल में बदलाव करेंगे, फिर यह एक घटना को आग लगा देगा। अपने अन्य रूपों में, आप उन परिवर्तनों की सदस्यता लेंगे जिनकी आप रुचि रखते हैं। ईवेंट हैंडलर में आप संपत्ति परिवर्तनों की सदस्यता लेने के लिए उपयोग करते हैं, तो आप इसका उपयोग करते हैं। इनवोक को यह देखने के लिए आवश्यक है कि आप यूआई बनाने के लिए सही धागे पर हैं या नहीं कॉल करें, यदि नहीं, तो इसका उपयोग करें। फार्म अपडेट करने के लिए वांछित विधि को कॉल करने के लिए BginginInvoke।

0
जोड़ा

आप ऐसा कर सकते हैं

  1. बाल प्रपत्र पर आवश्यक पैरामीटर के साथ एक सार्वजनिक विधि बनाएं और इसे मूल रूप से (वैध कलाकार के साथ)
  2. से कॉल करें
  3. बाल रूप पर सार्वजनिक संपत्ति बनाएं और इसे मूल रूप से (वैध कलाकार के साथ) एक्सेस करें
  4. फॉर्म के प्रारंभिक पैरामीटर सेट करने के लिए बाल रूप पर एक और कन्स्ट्रक्टर बनाएं
  5. कस्टम ईवेंट बनाएं और/या उपयोग करें (स्थिर) कक्षाएं

यदि आप गैर-मोडल रूपों का उपयोग कर रहे हैं तो सर्वश्रेष्ठ अभ्यास # 4 होगा।

0
जोड़ा

संपत्ति के साथ (हाइलाइट किया गया) मैं मेनफॉर्म क्लास का उदाहरण प्राप्त कर सकता हूं। लेकिन यह एक अच्छा अभ्यास है? आप क्या सलाह देते हैं?

इसके लिए मैं प्रॉपर्टी मेनफॉर्म इंस्टेंस का उपयोग करता हूं जो ऑनलोड मोड पर चलता है।

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;
using LightInfocon.Data.LightBaseProvider;
using System.Configuration;

namespace SINJRectifier
{

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            UserInterface userInterfaceObj = new UserInterface();
            this.chklbBasesList.Items.AddRange(userInterfaceObj.ExtentsList(this.chklbBasesList));
            MainFormInstance.MainFormInstanceSet = this; //Here I get the instance
        }

        private void btnBegin_Click(object sender, EventArgs e)
        {
            Maestro.ConductSymphony();
            ErrorHandling.SetExcecutionIsAllow();
        }
    }

    static class MainFormInstance  //Here I get the instance
    {
        private static MainForm mainFormInstance;

        public static MainForm MainFormInstanceSet { set { mainFormInstance = value; } }

        public static MainForm MainFormInstanceGet { get { return mainFormInstance; } }
    }
}
0
जोड़ा
  1. इसे संभालने के लिए अन्य फॉर्म को सूचित करने के लिए इवेंट हैंडलर का उपयोग करें।
  2. बच्चे के फॉर्म पर सार्वजनिक संपत्ति बनाएं और इसे मूल रूप से एक्सेस करें (वैध कलाकार के साथ)।
  3. फॉर्म के प्रारंभिक पैरामीटर सेट करने के लिए बच्चे के फॉर्म पर एक और कन्स्ट्रक्टर बनाएं
  4. कस्टम ईवेंट और/या उपयोग (स्थैतिक) वर्ग बनाएं।

यदि आप गैर-मोडल रूपों का उपयोग कर रहे हैं तो सबसे अच्छा अभ्यास # 4 होगा।

0
जोड़ा

चरण 1:

string regno, exm, brd, cleg, strm, mrks, inyear;

protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
    string url;
    regno = GridView1.Rows[e.NewEditIndex].Cells[1].Text;
    exm = GridView1.Rows[e.NewEditIndex].Cells[2].Text;
    brd = GridView1.Rows[e.NewEditIndex].Cells[3].Text;
    cleg = GridView1.Rows[e.NewEditIndex].Cells[4].Text;
    strm = GridView1.Rows[e.NewEditIndex].Cells[5].Text;
    mrks = GridView1.Rows[e.NewEditIndex].Cells[6].Text;
    inyear = GridView1.Rows[e.NewEditIndex].Cells[7].Text;

    url = "academicinfo.aspx?regno=" + regno + ", " + exm + ", " + brd + ", " +
          cleg + ", " + strm + ", " + mrks + ", " + inyear;
    Response.Redirect(url);
}

चरण 2:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string prm_string = Convert.ToString(Request.QueryString["regno"]);

        if (prm_string != null)
        {
            string[] words = prm_string.Split(',');
            txt_regno.Text = words[0];
            txt_board.Text = words[2];
            txt_college.Text = words[3];
        }
    }
}
0
जोड़ा