WinForm नियंत्रणों के लिए जिम्मेदार जिम्मेदारियों - नियंत्रण एक दूसरे के कार्यों के बारे में पता होना चाहिए?

मेरे पास एक फॉर्म पर कुछ हद तक नियंत्रण है:

  • एक चेक बॉक्स जो पृष्ठ पर अपने सभी चेक किए गए राज्य के आधार पर अन्य सभी नियंत्रण सक्षम/अक्षम करने के लिए ज़िम्मेदार है।
  • कुछ रेडियो बटन जो उनके चेक किए गए राज्यों के आधार पर पृष्ठ पर विशिष्ट नियंत्रण सक्षम/अक्षम करने के लिए ज़िम्मेदार हैं।
  • उपरोक्त नियंत्रणों द्वारा छेड़छाड़ किए गए अन्य नियंत्रण।

कुछ परिदृश्य उत्पन्न होते हैं:

  • जब फॉर्म प्रारंभ होता है, तो मैं चेकबॉक्स की स्थिति लोड करता हूं। फिर, यह फ़ॉर्म पर शेष नियंत्रण सक्षम या अक्षम करता है।
  • जैसा कि फॉर्म प्रारंभ करना जारी है, मैं रेडियो बटन की स्थिति लोड करता हूं। यदि रेडियो बटन चेक किया गया है लेकिन अक्षम है तो इसकी पिछली आवश्यकता को पूर्ववत करने का मौका है। इस प्रकार, मैं यह सुनिश्चित करने के लिए जांच करता हूं कि रेडियो बटन पहले सक्षम है।
  • फ़ॉर्म लोड होने के बाद उपयोगकर्ता रेडियो बटन को चेक या अनचेक कर सकता है। यह एक मामूली मामला है, मैं सिर्फ उस कोड को चलाता हूं जो अंतिम आवश्यकता को पूरा करता है। हालांकि, एक और मामला यह है कि उपयोगकर्ता चेकबॉक्स को चेक/अनचेक कर सकता है। जब चेकबॉक्स सक्षम हो जाता है तो यह पृष्ठ पर सभी नियंत्रणों को फिर से सक्षम करना चाहता है क्योंकि यह उन्हें अक्षम करता है। ऐसा करने से रेडियो बटन की आवश्यकताओं को तोड़ दिया जाएगा, हालांकि।

यह परिदृश्य ब्रूट फोर्स के साथ संभालने के लिए बहुत छोटा है। मैंने हाइलाइट करने के लिए कुछ विधियां बनाई हैं:

private void ChkBxSnmPv3OnCheckedChanged(object sender, EventArgs eventArgs)
{
    snmpSettingsErrorProvider.Clear();

    foreach (Control control in grpBxSNMPv3.Controls)
    {
        if (control != sender)
            control.Enabled = ((CheckBox)sender).Checked;
    }
}

private void rdBtnAuthNoPriv_CheckedChanged(object sender, EventArgs e)
{
    RadioButton authNoPrivRadioButton = ((RadioButton)sender);

    if (authNoPrivRadioButton.Enabled)
    {
        bool isChecked = authNoPrivRadioButton.Checked;

        SetControlState(cmbBxAuthProtocol, isChecked);
        SetControlState(mskdTxtBxAuthPassword, isChecked);
        SetControlState(mskdTxtBxAuthPasswordConfirm, isChecked);

        SetControlState(cmbBxPrivacyProtocol, !isChecked);
        SetControlState(mskdTxtBxPrivacyPassword, !isChecked);
        SetControlState(mskdTxtBxPrivacyPasswordConfirm, !isChecked);
    }
}
//More methods for other checkedChange and also for when rdBtn's enable.

लेआउट का असहज विचार:

enter image description here

जो भी कहा गया है, मेरे सवाल 'सरल' है:

  • विधियों को इस धारणा के बिना काम करना चाहिए कि अन्य विधियां मौजूद हैं। फिर भी, अगर मैं chkbx के अस्तित्व के rdbtn की तर्किक नींद रखता हूं तो मेरे पास कोड होगा जो एक-दूसरे से लड़ना होगा।

मैं अपना कोड इस तरह लिख सकता था:

private void ChkBxSnmPv3OnCheckedChanged(object sender, EventArgs eventArgs)
{
    snmpSettingsErrorProvider.Clear();

    txtBxEngineID = ((CheckBox)sender).Checked;
    rdBtnAuthNoPriv = ((CheckBox)sender).Checked;
    rdBtnAuthPriv = ((CheckBox)sender).Checked;
    rdBtnNoAuthNoPriv = ((CheckBox)sender).Checked;

    //Pass work for enabling Auth and Priv fields to rdBtn events.
}

यह समाधान अधिक कुशल और गारंटी है कि मुझे कोई झटका नहीं दिखाई देगा। फिर भी, इसका मतलब यह भी है कि पृष्ठ पर सभी नियंत्रणों को सक्षम करने के 'सफल समापन' के लिए मेरे chkBx को अब rdBtn के तर्क पर भरोसा करना है। क्या यह अच्छा प्रोग्रामिंग अभ्यास है?

3
जोड़ा संपादित
विचारों: 1
अरे खेद। मैं सहमत हूं - मेरी प्रारंभिक पोस्ट पर्याप्त समझ में नहीं आती है। मैं इसे आज संपादित करूँगा जब मेरे पास विरासत उद्देश्यों के लिए इसे और अधिक समझने योग्य बनाने के लिए कुछ समय होगा। हालांकि, मैं आपके दूसरे बिंदु से उलझन में हूं। अगर एक वर्ग शामिल है तो घटनाओं का कभी भी उपयोग नहीं किया जाना चाहिए? क्या आपने इसे वापस करने के लिए मेरे लिए पढ़ा है? कोड उपयोगकर्ता नियंत्रण पर है जो एक रूप में लोड होता है।
जोड़ा लेखक Sean Anderson, स्रोत
प्रश्न बहुत समझ में नहीं आता है, ये पहले से ही कोड के स्निपेट हैं जो form में मौजूद हैं। या UserControl, नहीं बता सकता है। कोड नहीं है जो नियंत्रण वर्ग के अंदर है। घटनाओं के बारे में कौन सा घटना है, किसी प्रकार का अन्य कोड बताता है कि कुछ दिलचस्प हुआ। यह कोड फ़ॉर्म में बहुत अधिक है, एकमात्र वर्ग जो इसे नियंत्रित करने वाले नियंत्रणों के संग्रह के बारे में कुछ भी जानता है।
जोड़ा लेखक Hans Passant, स्रोत

2 उत्तर

मुझे लगता है कि फॉर्म में रखने के लिए यह समझदार कोड है, हालांकि मैं कुछ सुझाव दूंगा;

1) कास्टिंग में एक मामूली प्रसंस्करण लागत है ताकि आपको लूप के अंदर कास्टिंग से बचना चाहिए। वास्तव में, एक सामान्य अवधारणा के रूप में, आपको एक लूप के अंदर किसी भी बार-बार कार्रवाई करने से बचना चाहिए जब परिणाम एक ही रहने की गारंटी है। तो आप अपनी पहली विधि को इस तरह सुधार सकते हैं;

private void ChkBxSnmPv3OnCheckedChanged(object sender, EventArgs eventArgs)
{
    snmpSettingsErrorProvider.Clear();

   //cast the sender once only
    CheckBox cb = sender as CheckBox;
    if (null == cb) return;

    foreach (Control control in grpBxSNMPv3.Controls)
    {
        if (control != sender)
            control.Enabled = cb.Checked;
    }
}

2) मैं सुझाव देता हूं कि सक्षम/अक्षम करने वाले तर्क को एक अलग विधि में ले जाएं, और उसके बाद इसे अपने नियंत्रण ईवेंट हैंडलर से कॉल करें। यह आपको किसी अन्य नियंत्रण से, उसी तर्क का पुन: उपयोग करने में सक्षम करेगा, जिसे आप तय करना चाहते हैं। घटनाओं को नियंत्रित करने के लिए कसकर युग्मन व्यवहार, मुझे डुप्लिकेट कोड की ओर जाता है। इस तरह;

private void ChkBxSnmPv3OnCheckedChanged(object sender, EventArgs eventArgs)
{
    snmpSettingsErrorProvider.Clear();

   //cast the sender once only
    CheckBox cb = sender as CheckBox;
    if (null == cb) return;

    SetEnabled(grpBxSNMPv3, cb.Checked, new[] { cb });
}

private void SetEnabled(Control parent, bool isEnabled, Control[] exludeControls)
{
    if (null == parent) return;

    foreach (Control control in parent.Controls)
    {
        if (!excludeControls.Contains(control))
            control.Enabled = isEnabled;
    }
}

अब आप किसी अन्य द्वारा निहित सभी नियंत्रणों को सक्षम/अक्षम करने के लिए एक पुन: प्रयोज्य विधि प्राप्त कर चुके हैं।

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

1
जोड़ा
सुझावों के लिए +1। मैंने वास्तव में अपने धागे को अपडेट करने से पहले इन सभी सुझावों का पालन किया - इतने महान दिमाग एक जैसे सोचते हैं। मैं आगे बढ़ गया और भविष्य के लोगों के लिए एक साफ समाधान पोस्ट किया। अगर आप इसके बारे में कुछ भी खराब देखते हैं तो मुझे बताएं। :)
जोड़ा लेखक Sean Anderson, स्रोत

यही वह है जो मैंने साथ समाप्त किया। मैं दो सूचीओं के अलावा इसे ठीक से ठीक कर रहा हूं। उन्हें शायद अपने नियंत्रण में होना चाहिए, लेकिन मैं इसे अभी तक करने के लिए खुद को नहीं ला सकता हूं।

public partial class DeviceSnmpSettings : UserControl, INotifyPropertyChanged
{
    private readonly List AuthenticationControls = new List(6);
    private readonly List PrivacyControls = new List(6);
    public event PropertyChangedEventHandler PropertyChanged;

    public DeviceSnmpSettings()
    {
        InitializeComponent();
        InitializeAuthControls();
        InitializePrivacyControls();
    }

    public DeviceSnmpSettings(Point location)
        : this()
    {
        Location = location;
    }

    //TODO: Move out into sub-user control?
    private void InitializeAuthControls()
    {
        AuthenticationControls.Add(lblAuthPassword);
        AuthenticationControls.Add(mskdTxtBxAuthPassword);
        AuthenticationControls.Add(lblAuthProtocol);
        AuthenticationControls.Add(cmbBxAuthProtocol);
        AuthenticationControls.Add(lblAuthPasswordConfirm);
        AuthenticationControls.Add(mskdTxtBxAuthPasswordConfirm);
    }
    //TODO: Move out into sub-user control?
    private void InitializePrivacyControls()
    {
        PrivacyControls.Add(lblPrivacyPassword);
        PrivacyControls.Add(mskdTxtBxPrivacyPassword);
        PrivacyControls.Add(lblPrivacyProtocol);
        PrivacyControls.Add(cmbBxPrivacyProtocol);
        PrivacyControls.Add(lblPrivacyPasswordConfirm);
        PrivacyControls.Add(mskdTxtBxPrivacyPasswordConfirm);
    }

    private bool SNMPv3Enabled
    {
        get { return chkBxSNMPv3.Checked; }
        set { chkBxSNMPv3.Checked = value; }
    }

    private SNMPV3Mode SecurityMode
    {
        get
        {
            SNMPV3Mode mode = SNMPV3Mode.NoAuthNoPriv;

            if (rdBtnAuthNoPriv.Checked)
                mode = SNMPV3Mode.AuthNoPriv;
            else if(rdBtnAuthPriv.Checked)
                mode = SNMPV3Mode.AuthPriv;

            return mode;
        }
        set
        {
            switch (value)
            {
                case SNMPV3Mode.NoAuthNoPriv:
                    rdBtnNoAuthNoPriv.Checked = true;
                    break;
                case SNMPV3Mode.AuthNoPriv:
                    rdBtnAuthNoPriv.Checked = true;
                    break;
                default:
                    rdBtnAuthPriv.Checked = true;
                    break;
            }

            OnSecurityModeChanged();
        }
    }

    protected virtual void OnSecurityModeChanged()
    {
        AuthenticationControls.ForEach(control => SetControlEnabledState(control, AuthenticationEnabled));
        PrivacyControls.ForEach(control => SetControlEnabledState(control, PrivacyEnabled));
        NotifyPropertyChanged("SecurityMode");
    }

    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    private bool AuthenticationEnabled
    {
        get
        {
            return SNMPv3Enabled && (SecurityMode == SNMPV3Mode.AuthPriv || SecurityMode == SNMPV3Mode.AuthNoPriv);
        }
    }

    private bool PrivacyEnabled
    {
        get { return SNMPv3Enabled && SecurityMode == SNMPV3Mode.AuthPriv; }
    }

    private void ChkBxSnmPv3OnCheckedChanged(object sender, EventArgs eventArgs)
    {
        SetControlEnabledStates();
    }

    private void SetControlEnabledStates()
    {
        snmpSettingsErrorProvider.Clear();

        foreach (Control control in grpBxSNMPv3.Controls)
        {
            //Check each of the lists for the control to prevent flickering.
            if (control != chkBxSNMPv3 && !AuthenticationControls.Contains(control) && !PrivacyControls.Contains(control))
                control.Enabled = SNMPv3Enabled;
        }

        //Need to validate that our radio button's checked state is reflected properly.
        AuthenticationControls.ForEach(control => SetControlEnabledState(control, AuthenticationEnabled));
        PrivacyControls.ForEach(control => SetControlEnabledState(control, PrivacyEnabled));
    }

    public void LoadFields(NetworkDiscovery networkDiscovery)
    {
        SNMPv3Enabled = networkDiscovery.Snmpv3Enabled;
        SecurityMode = networkDiscovery.SecurityMode;
        txtBxSNMPv3Username.Text = networkDiscovery.Username;
        mskdTxtBxAuthPassword.Text = networkDiscovery.AuthPassword;
        mskdTxtBxAuthPasswordConfirm.Text = networkDiscovery.AuthPassword;
        cmbBxAuthProtocol.SelectedItem = networkDiscovery.AuthProtocol.ToString();
        mskdTxtBxPrivacyPassword.Text = networkDiscovery.PrivacyPassword;
        mskdTxtBxPrivacyPasswordConfirm.Text = networkDiscovery.PrivacyPassword;
        cmbBxPrivacyProtocol.SelectedItem = networkDiscovery.PrivacyProtocol.ToString();

        SetControlEnabledStates();
    }

    private void SetControlEnabledState(Control control, bool enabled)
    {
        control.Enabled = enabled;
                    //Clear errors set on errorProvider when control is disabled.
        if (!control.Enabled)
            snmpSettingsErrorProvider.SetError(control, string.Empty);
    }

    private void rdBtnNoAuthNoPriv_CheckedChanged(object sender, EventArgs e)
    {
        if (((RadioButton)sender).Checked)
            SecurityMode = SNMPV3Mode.NoAuthNoPriv;
    }

    private void rdBtnAuthNoPriv_CheckedChanged(object sender, EventArgs e)
    {
        if (((RadioButton)sender).Checked)
            SecurityMode = SNMPV3Mode.AuthNoPriv;
    }

    private void rdBtnAuthPriv_CheckedChanged(object sender, EventArgs e)
    {
        if (((RadioButton)sender).Checked)
            SecurityMode = SNMPV3Mode.AuthPriv;
    }
}
0
जोड़ा