ComboBox- SelectionChanged घटना का पुराना मूल्य है, नया मूल्य नहीं


90

C #, .NET 4.0, VS2010।

WPF में नया। मैं अपने MainWindow पर एक ComboBox है। मैंने कॉम्बो बॉक्स के SelectionChanged इवेंट को झुका दिया। हालाँकि, यदि मैं ईवेंट हैंडलर में कॉम्बो बॉक्स के मूल्य की जांच करता हूं, तो इसका पुराना मूल्य है। यह एक "SelectionChanging" घटना की तरह लगता है, एक SelectionChanged घटना की तुलना में।

वास्तव में चयन के बाद मुझे कॉम्बो बॉक्स का नया मूल्य कैसे मिलेगा?

वर्तमान में:

this.MyComboBox.SelectionChanged += new SelectionChangedEventHandler(OnMyComboBoxChanged);

...
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = this.MyComboBox.Text;
}

ध्यान दें, मुझे वही व्यवहार मिलता है, अगर मैं ईवेंट ऑर्गन्स में पारित होने वाले ऑब्जेक्ट का उपयोग करता हूं, egeOriginalSource।


2
मैं बस एक ही मुद्दे पर ठोकर खाई - धन्यवाद! क्या यह वास्तव में एक बग है, और इसे SelectionChangingपहली जगह में नामित किया जाना चाहिए था ?
Jan

जवाबों:


109

MSDN के अनुसार e.AddedItems:

एक सूची मिलती है जिसमें वे आइटम होते हैं जिन्हें चुना गया था।

तो आप उपयोग कर सकते हैं:

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = (e.AddedItems[0] as ComboBoxItem).Content as string;
}

SelectedItemयदि आप निम्न stringमें Itemsसे मानों का उपयोग करते हैं, तो आप इसका उपयोग भी कर सकते हैं sender:

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = (sender as ComboBox).SelectedItem as string;
}

या

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;
}

चूंकि दोनों Contentऔर SelectedItemवस्तुएं हैं, इसलिए .ToString()इसके बजाय एक सुरक्षित दृष्टिकोण का उपयोग करना होगाas string


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

1
हाँ, मुझे लगता है कि इसकी वजह से बदलाव हुआ है, लेकिन प्रतिबद्ध नहीं किया गया है? यह सिर्फ एक अनुमान है। आप चयनित आइटम का पाठ प्राप्त करने में सक्षम हो सकते हैं, मेरा संपादन देखें।
स्वदेवमन ev१

3
ComboBox.SelectedItemके पास एक संपत्ति नहीं है जिसे बुलाया गया है Text, लेकिन आप कर सकते हैं ComboBox.SelectedItem as string(हालांकि यह केवल तभी काम कर सकता है जब आप इसके लिए उपयोग stringकरते हैं Items- कुछ और परीक्षण नहीं किया गया)
musefan

बस स्ट्रिंग पाठ = (स्ट्रिंग) e.AddedItems [0];
इगोर सेमिन

बिना किसी कारण के चीजों को जटिल न करें। SelectValue प्रॉपर्टी का उपयोग करके आप आसानी से एक चयनित कॉम्बो बॉक्स मान प्राप्त कर सकते हैं: YourComboBoxName.SelectedValue.ToString ()। चयनित दृश्य संपत्ति के पीछे के रूप में परिभाषित किया गया है: चयनितवैल्यू {प्राप्त करें; सेट;} इसका मतलब है कि आप इसे कॉम्बो बॉक्स का मान प्राप्त करने या सेट करने के लिए उपयोग कर सकते हैं। सेलेक्ट इट का उपयोग करना एक प्रभावी तरीका नहीं है, क्योंकि इसमें कॉम्बो बॉक्स मूल्य प्राप्त करने की आवश्यकता होती है, क्योंकि इसमें बहुत सारे बदलावों की आवश्यकता होती है।
सैम तोमाशी

59

यहां जांचने का सही मूल्य है चयनित आइटम।

एक कॉम्बो बॉक्स अपने दो भागों के साथ एक समग्र नियंत्रण है:

  1. पाठ भाग : इस भाग का मान कॉम्बोबॉक्स के पाठ गुण से मेल खाता है ।
  2. चयनकर्ता भाग (यानी "ड्रॉप-डाउन" भाग): इस भाग में चयनित आइटम चयनित संपत्ति से मेल खाती है ।

विस्तृत ComboBox पार्ट्स

कॉम्बो बॉक्स का विस्तार होने के तुरंत बाद (ऊपर एक नया मूल्य चुनने से पहले) छवि को लिया गया था। इस बिंदु पर टेक्स्ट और सेलेक्टिम दोनों "इंफो" हैं, यह मानते हुए कि कॉम्बो बॉक्स आइटम तार थे। यदि ComboBox आइटम बजाय सभी थे एक Enum के मूल्यों "LogLevel" कहा जाता है, SelectedItem वर्तमान में होगा LogLevel.Info

जब ड्रॉप-डाउन में किसी आइटम पर क्लिक किया जाता है, का मूल्य SelectedItem बदल गया है और SelectionChanged घटना उठाया जाता है। पाठ संपत्ति,, अभी तक अपडेट नहीं है, हालांकि के रूप में पाठ भाग जब तक बाद अपडेट नहीं होती SelectionChanged हैंडलर समाप्त हो गया है। इसे हैंडलर में एक ब्रेकपॉइंट लगाकर और नियंत्रण को देखते हुए देखा जा सकता है:

चयनचैन्ड हैंडलर में ब्रेकपॉइंट पर कॉम्बोबॉक्स

चूंकि पाठ भाग इस बिंदु पर अद्यतन नहीं किया गया है, पाठ गुण पहले चयनित मान लौटाता है।


2
पूर्ण विस्तार और इसने मेरे बाइंडिंग को सही चयनित इटेम के बजाय पाठ संपत्ति पर महसूस करने में मदद की।
cmousset

1
@DaveKidder महान उदाहरण! +1
रयान विल्सन

46

यदि आप कॉम्बो बॉक्स का वर्तमान मूल्य चाहते हैं, तो SelectionChanged के बजाय DropDownClosed इवेंट का उपयोग करें।

private void comboBox_DropDownClosed(object sender, EventArgs e)
{
   MessageBox.Show(comboBox.Text) 
}

क्या वाकई इतना आसान है।


10
@jvelez मुझे लगता है कि कीबोर्ड का उपयोग करते समय यह आग नहीं लगेगा।
NoviceProgrammer

वह बेकार है। NoviceProgrammer जो जानता था ...!
छिपा

10

यह मेरे लिए काम किया:

private void AppName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   ComboBoxItem cbi = (ComboBoxItem)AppName.SelectedItem;
   string selectedText = cbi.Content.ToString();
}

किसी भी तरह केवल चयनित आइटम नए आइटम से पॉप्युलेट हो जाता है, चयनितवैल्यू नहीं।
मौरिस

7

यह मेरे लिए काम किया:

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    var text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;            
}

यह बहुत महत्वपूर्ण है। स्वीकृत उत्तर स्पष्ट रूप से नहीं दिखाता है senderजिसमें सही है SelectedItem
जेस

3

निम्नलिखित घटना को कॉम्बोबॉक्स में पाठ के किसी भी परिवर्तन के लिए निकाल दिया जाता है (जब चयनित सूचकांक को बदल दिया जाता है और जब पाठ को संपादित करके बदल दिया जाता है)।

<ComboBox IsEditable="True" TextBoxBase.TextChanged="cbx_TextChanged" />

1
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string newItem = ((DataRowView) e.AddedItems[0]).Row.ItemArray[0].ToString();
}

5
कृपया केवल-कोड उत्तर न दें। कृपया इसका स्पष्टीकरण दें कि आपका समाधान उत्तर क्यों है।
ली टेलर 12

1

दूसरा विकल्प मेरे काम नहीं आया क्योंकि .Text तत्व दायरे से बाहर था (C # 4.0 VS2008)। ये था मेरा उपाय ...

string test = null;
foreach (ComboBoxItem item in e.AddedItems)
{
   test = item.Content.ToString();
   break;
}

0

मुझे VB.NET में इसे हल करने की आवश्यकता थी। यहाँ मुझे लगता है कि काम करने लगता है:

Private Sub ComboBox1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ComboBox_AllSites.SelectionChanged
   Dim cr As System.Windows.Controls.ComboBoxItem = ComboBox1.SelectedValue
   Dim currentText = cr.Content
   MessageBox.Show(currentText)
End Sub

0

यह अजीब है कि SelectItem ताजा डेटा रखता है, जबकि SelectValue नहीं करता है। मेरे लिए एक बग की तरह लगता है। यदि कॉम्बोक्स में आपके आइटम कॉम्बो बॉक्स इट्स के अलावा अन्य वस्तुएं हैं, तो आपको कुछ इस तरह की आवश्यकता होगी: (मेरी सामग्री ComboBoxमें शामिल हैं KeyValuePair)

var selectedItem = (KeyValuePair<string, string>?)(sender as ComboBox).SelectedItem;
if (!selectedItem.HasValue)
    return;

string selectedValue = selectedItem.Value.Value;  // first .Value gets ref to KVPair

ComboBox.SelectedItemअशक्त हो सकता है, जबकि विज़ुअल स्टूडियो मुझे बताता रहता है कि KeyValuePairअशक्त नहीं हो सकता। इसलिए मैंने SelectedItemएक अशक्त को कास्ट किया KeyValuePair<string, string>?। फिर मैं जांचता हूं कि क्या selectedItemइसके अलावा कोई मूल्य है null। यह दृष्टिकोण आपके चयनित आइटम को वास्तव में टाइप करने के लिए लागू होना चाहिए।


0

यदि आपको वास्तव में SelectionChangedघटना की आवश्यकता है , तो सबसे अच्छा उत्तर है स्वदेवमेन 81 का उत्तर। हालाँकि, यदि आप WPF से शुरुआत कर रहे हैं, तो आप सीखना चाह सकते हैं कि WPF तरीके से काम कैसे करें, जो पुराने विंडोज फॉर्म दिनों की तुलना में अलग है जो SelectionChangedWPF और मॉडल व्यू व्यूमॉडल पैटर्न के साथ घटनाओं पर भरोसा करते थे , आपको चाहिए बाइंडिंग का उपयोग करें। यहाँ एक कोड उदाहरण है:

// In the Views folder: /Views/MyWindow.xaml:
// ...
<ComboBox ItemsSource="{Binding MyViewModel.MyProperties, RelativeSource={RelativeSource AncestorType=Window}}"
         SelectedItem="{Binding MyViewModel.MyProperty  , RelativeSource={RelativeSource AncestorType=Window}}" />
// ...



// In the Views folder: /Views/MyWindow.xaml.cs:
public partial class MyWindow : Window
{
    public  MyViewModelClass MyViewModel {
        get { return _viewModel; }
        private set { _viewModel = value;}
    }

    public MyWindow()
    {
        MyViewModel.PropertyChanged += MyViewModel_PropertyChanged;

    }

    void MyViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "MyProperty")
        {
            // Do Work
            // Put your logic here!
        }
    }
}

using System.ComponentModel;

// In your ViewModel folder: /ViewModels/MyViewModelClass.cs:
public class MyViewModelClass : INotifyPropertyChanged
{
    // INotifyPropertyChanged implementation:
    private void NotifyPropertyChanged(string propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
    public event PropertyChangedEventHandler PropertyChanged;

    // Selected option:
    private string _myProperty;
    public  string  MyProperty {
        get { return _myProperty; }
        set { _myProperty = value; NotifyPropertyChanged("MyProperty"); }
    }

    // Available options:
    private List<string> _myProperties;
    public  List<string>  MyProperties {
        get { return _myProperties; }
        set { _myProperties = value; NotifyPropertyChanged("MyProperties"); }
    }

}

0
private void indBoxProject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    int NewProjID = (e.AddedItems[0] as kProject).ProjectID;
    this.MyProject = new kProject(NewProjID);
    LoadWorkPhase();
}

के उपयोग e.AddedItems[0] as kProjectजहां kProject एक वर्ग है कि रखती डेटा मेरे लिए काम किया के रूप में यह RemovedItems [0] इससे पहले कि मैं यह स्पष्ट भेद बना दिया है करने के लिए दोषी था। धन्यवाद SwDevMan81 प्रारंभिक जानकारी के लिए जिसने मेरे लिए इस प्रश्न का उत्तर दिया।


0

बिना किसी कारण के चीजों को जटिल न करें। SelectValue प्रॉपर्टी का उपयोग करके आप आसानी से एक चयनित कॉम्बो बॉक्स मान प्राप्त कर सकते हैं: YourComboBoxName.SelectedValue.ToString ()।

चयनित दृश्य संपत्ति के पीछे के रूप में परिभाषित किया गया है: चयनितवैल्यू {प्राप्त करें; सेट;} इसका मतलब है कि आप इसे कॉम्बो बॉक्स का मान प्राप्त करने या सेट करने के लिए उपयोग कर सकते हैं।

सिलेक्ट इट का उपयोग करना एक प्रभावी तरीका नहीं है, क्योंकि इसमें कॉम्बो बॉक्स मूल्य प्राप्त करने की आवश्यकता है क्योंकि इसमें बहुत अधिक मात्रा में बदलाव की आवश्यकता होती है।


0

आप Combobox नियंत्रण के SelectionChanged इवेंट में SelectIndex या SelectValue या SelectItem गुण की जाँच कर सकते हैं।


-2

यह आपके लिए काम करना चाहिए ...

int myInt= ((data)(((object[])(e.AddedItems))[0])).kid;

2
क्या आप बता सकते हैं कि यह सवाल का जवाब कैसे देता है?
नाथन तुग्गी

-3

मैंने इसे ड्रॉपडाउन क्लोज्ड इवेंट का उपयोग करके हल किया क्योंकि यह मूल्य परिवर्तित होने के बाद थोड़ा आग लगाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.