DataGridView को बिना डेटा सोर्स को फ़िल्टर किए


95

मैं सी # विजुअल स्टूडियो 2010 में उपयोगकर्ता नियंत्रण विकसित कर रहा हूं - डेटाग्रिडव्यू को छानने के लिए एक तरह का "त्वरित खोज" टेक्स्टबॉक्स। यह 3 प्रकार के डेटाग्रेडव्यू डेटा स्रोतों के लिए काम करना चाहिए: डेटाटेबल, डेटाबाइंडिंग और डेटासेट। मेरी समस्या डेटासेट ऑब्जेक्ट से डेटाटेबल को फ़िल्टर करने के साथ है, जो डेटाग्रिड व्यू पर प्रदर्शित होती है।

वहाँ 3 मामले हो सकते हैं (उदाहरण के लिए मानक WinForm आवेदन के साथ DataGridView और उस पर TextBox) - पहले 2 ठीक काम कर रहे हैं, मुझे 3 के साथ समस्या है:

1. datagridview.DataSource = dataTable: यह काम करता है
इसलिए मैं सेटिंग द्वारा फ़िल्टर कर सकता हूं: dataTable.DefaultView.RowFilter = "country LIKE '% s%'";

DataTable dt = new DataTable();

private void Form1_Load(object sender, EventArgs e)
{
    dt.Columns.Add("id", typeof(int));
    dt.Columns.Add("country", typeof(string));

    dt.Rows.Add(new object[] { 1, "Belgium" });
    dt.Rows.Add(new object[] { 2, "France" });
    dt.Rows.Add(new object[] { 3, "Germany" });
    dt.Rows.Add(new object[] { 4, "Spain" });
    dt.Rows.Add(new object[] { 5, "Switzerland" });
    dt.Rows.Add(new object[] { 6, "United Kingdom" });

    dataGridView1.DataSource = dt;
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());

    dt.DefaultView.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);

    MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
} 

2. datagridview.DataSource = बाइंडिंग स्रोत: यह काम करता है
इसलिए मैं सेटिंग द्वारा फ़िल्टर कर सकता हूं : बाइंडिंग स्रोत .ilter = "देश LIKE '% s%'";

DataTable dt = new DataTable();
BindingSource bs = new BindingSource();

private void Form1_Load(object sender, EventArgs e)
{
    dt.Columns.Add("id", typeof(int));
    dt.Columns.Add("country", typeof(string));

    dt.Rows.Add(new object[] { 1, "Belgium" });
    dt.Rows.Add(new object[] { 2, "France" });
    dt.Rows.Add(new object[] { 3, "Germany" });
    dt.Rows.Add(new object[] { 4, "Spain" });
    dt.Rows.Add(new object[] { 5, "Switzerland" });
    dt.Rows.Add(new object[] { 6, "United Kingdom" });

    bs.DataSource = dt;
    dataGridView1.DataSource = bs;
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());

    bs.Filter = string.Format("country LIKE '%{0}%'", textBox1.Text);

    MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
}

3. डेटाग्रिडव्यूड.डाटासोर्स = डेटासोर्स; datagridview.DataMember = "TableName":
यह तब काम नहीं करता है जब आप डिज़ाइनर का उपयोग करके किसी टेबल को डिज़ाइन करते हैं: टूलबॉक्स से डेटासेट को फॉर्म पर रखें, डेटाटैब इसमें जोड़ें और फिर डेटाट्रेडव्यूड डेटा सेट करें। डेटा स्रोत; और डाटाग्रिडव्यू। डॅटमम्बर = "टेबलनेम"।
नीचे दिए गए कोड इन कार्यों का दिखावा करते हैं:

DataSet ds = new DataSet();
DataTable dt = new DataTable();

private void Form1_Load(object sender, EventArgs e)
{
    dt.Columns.Add("id", typeof(int));
    dt.Columns.Add("country", typeof(string));

    dt.Rows.Add(new object[] { 1, "Belgium" });
    dt.Rows.Add(new object[] { 2, "France" });
    dt.Rows.Add(new object[] { 3, "Germany" });
    dt.Rows.Add(new object[] { 4, "Spain" });
    dt.Rows.Add(new object[] { 5, "Switzerland" });
    dt.Rows.Add(new object[] { 6, "United Kingdom" });

    ds.Tables.Add(dt);
    dataGridView1.DataSource = ds;
    dataGridView1.DataMember = dt.TableName;
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString());  
    //it is not working
    ds.Tables[0].DefaultView.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);

    MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString());
}

यदि आप इसका परीक्षण करते हैं - हालाँकि डेटाटेबल को फ़िल्टर किया जाता है (ds.Tables [0] .DefaultView.Count बदलाव), डेटाग्रिड्यूव्यू अपडेट नहीं है ... मैं किसी भी समाधान के लिए लंबे समय से देख रहा हूं, लेकिन समस्या यह है कि डेटास्क्रिप्शन नहीं कर सकता परिवर्तन - जैसा कि यह अतिरिक्त नियंत्रण है, मैं इसे प्रोग्रामर के कोड के साथ गड़बड़ नहीं करना चाहता।

मुझे पता है कि संभावित समाधान हैं:
-
डेटाबाइंड का उपयोग करके डेटाटेबल को बाइंड करना और डेटाबाइंड का उपयोग करना उदाहरण 2 के रूप में: लेकिन यह कोड लिखने के दौरान प्रोग्रामर पर निर्भर है, - डेटास्सोर्स को बाइंडिंग सोर्स में बदलने के लिए, डेटाग्रिड व्यू.डॉटसोर्स = dataSet.Tables [0], या प्रोग्राम को डिफ़ॉल्ट रूप से: हालांकि, यह डेटा स्रोत बदलता है। तो समाधान:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());

    DataView dv = ds.Tables[0].DefaultView;
    dv.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
    dataGridView1.DataSource = dv;

    MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());
}

जैसा कि आप MessageBox के डेटा स्रोत पर देख रहे हैं, स्वीकार्य नहीं है ...

मैं ऐसा नहीं करना चाहता, क्योंकि यह संभव है कि एक प्रोग्रामर इसके समान कोड लिखता है:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    MessageBox.Show("DataSource type BEFORE = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());

    DataSet dsTmp = (DataSet)(dataGridView1.DataSource);   //<--- it is OK 

    DataView dv = ds.Tables[0].DefaultView;
    dv.RowFilter = string.Format("country LIKE '%{0}%'", textBox1.Text);
    dataGridView1.DataSource = dv;   //<--- here the source is changeing from DataSet to DataView

    MessageBox.Show("DataSource type AFTER = " + dataGridView1.DataSource.GetType().ToString(), ds.Tables[0].DefaultView.Count.ToString());

    dsTmp = (DataSet)(dataGridView1.DataSource);    //<-- throws an exception: Unable to cast object DataView to DataSet
}

वह ऐसा कर सकता है, जैसे उसने डिज़ाइन में डेटासेट और डेटामेम्बर के साथ डेटाग्रिड्यू डिज़ाइन किया। कोड संकलित किया जाएगा, हालांकि, एक फिल्टर का उपयोग करने के बाद, यह एक अपवाद फेंक देगा ...

तो सवाल यह है: मैं डेटासेट को डेटासेट में कैसे फ़िल्टर कर सकता हूं और डेटास्ग्रेव पर परिणाम को बिना डेटास्रोत को दूसरे में बदले कैसे दिखा सकता हूं? मैं डेटाटेबल को उदाहरण 1 से सीधे फ़िल्टर क्यों कर सकता हूं, जबकि डेटासेट से डेटाटेबल को फ़िल्टर करना काम नहीं कर रहा है? शायद यह DataTable उस मामले में DataGridView के लिए बाध्य नहीं है?

कृपया ध्यान दें, कि मेरी समस्या मुद्दों को डिजाइन करने से है, इसलिए समाधान 3 उदाहरण पर काम करना चाहिए।


1
सभी मूल्यवान टिप्पणियों और समाधानों के अलावा मेरे 2 सेंट। यहां एक लेख है जो डेटा-बाउंड डेटाग्रिड व्यू को इस तरह से फ़िल्टर करने के पेशेवरों और विपक्षों के बारे में बताता है और आपको उस बेहतर तरीके से करने के कुछ विचार देता है।
TecMan

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

मुझे TecMan टिप्पणी पसंद है। आप फ़िल्टर संपत्ति (कम काम करता है, लेकिन केवल ADO.Net डेटाटेबल के साथ प्रयोग करने योग्य) या संपूर्ण नियंत्रण को अपने नियंत्रण में कर (अधिक काम करता है, लेकिन किसी भी चीज़ के साथ काम करना चाहिए) IBIBListView इंटरफ़ेस को फ़िल्टर करने का काम सौंप सकता है।
मार्को गुइगार्ड

जवाबों:


143

मैंने इसी तरह की समस्या पर सिर्फ एक घंटा बिताया। मेरे लिए जवाब शर्मनाक सरल निकला।

(dataGridViewFields.DataSource as DataTable).DefaultView.RowFilter = string.Format("Field = '{0}'", textBoxFilter.Text);

2
इस घटना को टेक्स्टबॉक्स में कैसे बांधें
अरुण प्रसाद ES

7
फ़िल्टरिंग सिंटैक्स यहाँ पाया जा सकता है: csharp-examples.net/dataview-rowfilter
Sal

DataTable का उपयोग स्रोत के रूप में msdn.microsoft.com/en-us/library/… केIBindingListView अनुसार लागू करने की समस्या के आसपास हो जाता है
जेरेमी थॉम्पसन

मुझे यह त्रुटि मिली: Object reference not set to an instance of an object.ग्रिड व्यू के लिए।
21

आपका डेटा स्रोत क्या है? मेरा उदाहरण मानता है कि आप एक DataTable का उपयोग कर रहे हैं। यदि आप कुछ और उपयोग कर रहे हैं, तो अपनी कास्टिंग की जाँच करें। मेरे उदाहरण में "डेटाटेबल के रूप में"।
ब्रैड ब्रूस

22

मैंने फ़िल्टर लागू करने के लिए एक सामान्य विवरण विकसित किया है:

string rowFilter = string.Format("[{0}] = '{1}'", columnName, filterValue);
(myDataGridView.DataSource as DataTable).DefaultView.RowFilter = rowFilter;

वर्ग कोष्ठक स्तंभ नाम में रिक्त स्थान के लिए अनुमति देते हैं।

इसके अतिरिक्त, यदि आप अपने फ़िल्टर में कई मान शामिल करना चाहते हैं, तो आप प्रत्येक अतिरिक्त मान के लिए निम्न पंक्ति जोड़ सकते हैं:

rowFilter += string.Format(" OR [{0}] = '{1}'", columnName, additionalFilterValue);

12

एक सरल तरीका डेटा को अनुप्रस्थ करना है, और Visibleसंपत्ति के साथ लाइनों को छिपाना है ।

// Prevent exception when hiding rows out of view
CurrencyManager currencyManager = (CurrencyManager)BindingContext[dataGridView3.DataSource];
currencyManager.SuspendBinding();

// Show all lines
for (int u = 0; u < dataGridView3.RowCount; u++)
{
    dataGridView3.Rows[u].Visible = true;
    x++;
}

// Hide the ones that you want with the filter you want.
for (int u = 0; u < dataGridView3.RowCount; u++)
{
    if (dataGridView3.Rows[u].Cells[4].Value == "The filter string")
    {
        dataGridView3.Rows[u].Visible = true;
    }
    else
    {
        dataGridView3.Rows[u].Visible = false;
    }
}

// Resume data grid view binding
currencyManager.ResumeBinding();

बस एक विचार ... यह मेरे लिए काम करता है।


जैसे कि कोई व्यक्ति जो मैन्युअल रूप से पॉपुलेट कर रहा है DataGridView, यह पूरी तरह से काम करता है। :) हालांकि मैंने बिना किसी को दिए foreachऔर सीधे इस्तेमाल किया । यही कारण है कि अगर फिल्टर स्ट्रिंग खाली है सच है। row.Visible = showAll || <condition>;ifshowAll
एंड्रयू

महान विचार क्योंकि इस मामले में हम डेटा स्रोत के प्रकार से बंधे नहीं हैं। न ही कोई डेटाटेबल।
mshakurov

पूरी तरह से काम किया है, और खोज तर्क में सुधार के लिए हम dataGridView3.Rows अगर हालत होने के लिए [u] .Cells [4] .Value.ToString () indexOf ( "फिल्टर स्ट्रिंग")> = 0 बदल सकते हैं।
अली अली

1

आप अपने डेटा स्रोत से DataView ऑब्जेक्ट बना सकते हैं । यह आपको डेटा स्रोत को सीधे संशोधित किए बिना अपने डेटा को फ़िल्टर और सॉर्ट करने की अनुमति देगा।

इसके अलावा, dataGridView1.DataBind();डेटा स्रोत सेट करने के बाद कॉल करना याद रखें ।


2
उत्तर देने के लिए आपका शुक्रिया। हां, DataView ऑब्जेक्ट बनाया जा सकता है, हालांकि यह DataSource प्रकार बदलता है, कृपया अंतिम कोड देखें। मैंने इस कारण को संशोधित किया है कि मैं पिछली पोस्ट में इससे बचना चाहता हूं। WinGorms में dataGridView1.DataBind () विधि मौजूद नहीं है, मुझे लगता है कि यह ASP से है।
mj82

0

// "टिप्पणी" फ़िल्टर डेटाग्रेड को डेटासेट के बिना, पूरी तरह से काम करता है।

            (dg.ItemsSource as ListCollectionView).Filter = (d) =>
            {
                DataRow myRow = ((System.Data.DataRowView)(d)).Row;
                if (myRow["FName"].ToString().ToUpper().Contains(searchText.ToString().ToUpper()) || myRow["LName"].ToString().ToUpper().Contains(searchText.ToString().ToUpper()))
                    return true; //if want to show in grid
                return false;    //if don't want to show in grid
            };         

0

मेरे पास DataGridView में स्वचालित खोज पर एक स्पष्ट प्रस्ताव है

यह एक उदाहरण है

private void searchTb_TextChanged(object sender, EventArgs e)
    {
        try
        {
            (lecteurdgview.DataSource as DataTable).DefaultView.RowFilter = String.IsNullOrEmpty(searchTb.Text) ?
                "lename IS NOT NULL" :
                String.Format("lename LIKE '{0}' OR lecni LIKE '{1}' OR ledatenais LIKE '{2}' OR lelieu LIKE '{3}'", searchTb.Text, searchTb.Text, searchTb.Text, searchTb.Text);
        }
        catch (Exception ex) {
            MessageBox.Show(ex.StackTrace);
        }
    }

साथ नकल कर सकते हैं stackoverflow.com/questions/5843537/...
टोनी दांग

-2

मुझे उस समस्या को ठीक करने का एक सरल तरीका मिला। बाध्यकारी डेटाग्रिड्यूव में आपने अभी-अभी किया है:datagridview.DataSource = dataSetName.Tables["TableName"];

यदि आप कोड पसंद करते हैं:

datagridview.DataSource = dataSetName;
datagridview.DataMember = "TableName";

फ़िल्टर करने पर डेटाग्रेडव्यू फिर से डेटा लोड नहीं करेगा।

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