ডেটাসোর্স পরিবর্তন না করে ডেটাগ্রিডভিউ ফিল্টার করছে


95

আমি সি # ভিজ্যুয়াল স্টুডিও 2010-এ ব্যবহারকারীর নিয়ন্ত্রণ বিকাশ করছি - ডেটাগ্রিডভিউ ফিল্টার করার জন্য এক ধরণের "কুইক ফাইন্ড" টেক্সটবক্স। এটি 3 ধরণের ডেটাগ্রিডভিউ ডেটাসোর্সের জন্য কাজ করা উচিত: ডেটা টেবিল, ডেটাবাইন্ডিং এবং ডেটাসেট। আমার সমস্যাটি ডেটাগ্রিডভিউতে প্রদর্শিত ডেটাসেট অবজেক্ট থেকে ডেটা টেবিল ফিল্টার করা নিয়ে।

3 টি কেস থাকতে পারে (এটিতে ডাটাগ্রিডভিউ এবং টেক্সটবক্সের সাথে স্ট্যান্ডার্ড উইনফর্ম অ্যাপ্লিকেশনটির উদাহরণ) - প্রথম 2 টি ঠিক আছে, আমার তৃতীয়টি সমস্যা রয়েছে:

১. ডেটাগ্রিডভিউ।ডাটাসোর্স = ডেটা টেবিল: এটি কাজ করে
তাই আমি সেটিংস দ্বারা ফিল্টার করতে পারি: ডেটাট্যাব.ডাফল্টভিউ।রোফিল্টার = "দেশ লাইক '% 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());
} 

২. ডেটাগ্রিডভিউ।ডাটাসোর্স = বাইন্ডিংসোর্স: এটি কাজ করে
যাতে আমি সেটিংস দ্বারা ফিল্টার করতে পারি: বাইন্ডিংসোর্স.ফিল্টার = "দেশ লাইক '% 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. ডেটাগ্রিডভিউ.ডাটাসোর্স = ডেটাসোর্স; ডেটাগ্রিডভিউ.ডাটা মেম্বার = "টেবিলনেম": এটি কাজ করে না
যখন আপনি ডিজাইনার ব্যবহার করে কোনও সারণি ডিজাইন করেন: ফর্মটি সরঞ্জামবক্স থেকে ডেটাসেট রাখুন, এতে ডেটা টেবিল যুক্ত করুন এবং তারপরে ডেটাগ্রিডভিউ সেট করুন; ডেটাসোর্স = ডেটাসোর্স; এবং ডেটাগ্রিডভিউ.ডাটা মেম্বার = "টেবিলনাম"।
নীচের কোডগুলি এই অপারেশনগুলির ভান করে:

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]। ডেফল্টভিউ.কাউন্ট পরিবর্তন), ডেটাগ্রিডভিউ আপডেট করা হয় না ... আমি কোনও সমাধানের জন্য দীর্ঘ সময় ধরে খুঁজছি, তবে সমস্যাটি ডেটাসোর্স করতে পারে না পরিবর্তন - এটি অতিরিক্ত নিয়ন্ত্রণ হিসাবে, আমি এটি প্রোগ্রামারের কোডের সাথে গোলমাল করতে চাই না।

আমি জানি সম্ভাব্য সমাধানগুলি
হ'ল : - ডেটাবেন্ডিং ব্যবহার করে ডেটাসেট থেকে ডেটা টেবিল বেঁধে রাখুন এবং উদাহরণ 2 হিসাবে এটি ব্যবহার করুন: তবে কোড লেখার সময় এটি প্রোগ্রামারের উপর
নির্ভর করে - ডাটাসোর্সকে বাইন্ডিংসোর্স, ডেটাগ্রিডভিউ.ডাটাসোর্স = ডেটাসেট.ট্যাবলস [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());
}

আপনি মেসেজবক্সের ডেটাসোর্সে যেমন দেখতে পাচ্ছেন তেমন গ্রহণযোগ্য নয় ...

আমি এটি করতে চাই না, কারণ এটি সম্ভব যে কোনও প্রোগ্রামার এই জাতীয় কোডটি লিখেছেন:

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 থেকে সরাসরি ফিল্টার করতে পারি, যখন ডেটাসেট থেকে ডেটা টেবিল ফিল্টার করা কাজ করছে না? সম্ভবত এটি ডেটাগ্রিডটি সেই ক্ষেত্রে ডেটাগ্রিডভিউয়ের সাথে আবদ্ধ নয়?

দয়া করে মনে রাখবেন, আমার সমস্যাটি ডিজাইনের সমস্যাগুলি থেকে শুরু করে, সুতরাং সমাধানটি উদাহরণস্বরূপ 3 এ কাজ করা উচিত।


4
সমস্ত মূল্যবান মন্তব্য এবং সমাধান ছাড়াও আমার 2 সেন্ট। এখানে একটি নিবন্ধ যা ডেটা-বেঁধে থাকা ডেটাগ্রিডভিউকে এইভাবে ফিল্টারিংয়ের পক্ষে মতামতগুলি বর্ণনা করে এবং কীভাবে আরও ভাল করতে হয় সে সম্পর্কে আপনাকে কিছু ধারণা দেয়।
টেকম্যান

পুনরাবৃত্তিটি ক্ষমা করুন তবে আমি মনে করি প্রতিবার আমার প্রস্তাব কার্যকর হয় না। আসলে, কখনও কখনও একটি ব্যতিক্রম প্রত্যাহার করা হয়, যা আমার কোডের সম্ভাবনা নেই। একটি বন্ডিংসোর্স দিয়ে ফিল্টার করার চেষ্টা করছেন আপনার কাছে ভাল কোড করার প্রতিটি সুযোগ রয়েছে। তারিখের মতো: বাইন্ডিংসোর্স.ফিল্টার = স্ট্রিং.ফর্ম্যাট .....
কাউকেপ আর্নল্ড

আমি টেকম্যান মন্তব্য পছন্দ করি। আপনি ফিল্টারিংয়ের কাজ ফিল্টার সম্পত্তি দ্বারা আইবিন্ডিংলিস্টভিউ ইন্টারফেসে অর্পণ করতে পারেন (কম কাজ তবে শুধুমাত্র সত্যই ADO.Net ডেটাটেবলের সাথে ব্যবহারযোগ্য) বা আপনার নিয়ন্ত্রণে পুরো কাজটি (আরও কাজ করে তবে কিছু দিয়ে কাজ করা উচিত)।
মার্কো গিগনার্ড

উত্তর:


144

আমি ঠিক একটি ঘন্টা একই সমস্যা ব্যয়। আমার জন্য উত্তরটি বিব্রতকরভাবে সহজ হয়ে উঠল।

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

4
এই ইভেন্টটিকে পাঠ্যবক্সে কীভাবে আবদ্ধ করবেন
অরুণ প্রসাদ ES

7
ফিল্টারিং সিনট্যাক্সটি এখানে পাওয়া যাবে: csharp-eximar.net/dataview-rowfilter
সাল

উত্স হিসাবে একটি ডেটা টেবিল ব্যবহার করে এমএসডিএন.মাইক্রোসফটকমIBindingListView / en
জেরেমি থম্পসন

আমি এই ত্রুটিটি পেয়েছি: Object reference not set to an instance of an object.গ্রিডভিউয়ের জন্য।
সি 8

আপনার তথ্য উত্স কি? আমার উদাহরণ ধরে নিয়েছে যে আপনি ডেটা টেবিল ব্যবহার করছেন। আপনি যদি অন্য কিছু ব্যবহার করে থাকেন তবে আপনার ingালাই পরীক্ষা করুন। আমার উদাহরণে "ডেটা টেবিল হিসাবে"।
ব্র্যাড ব্রুস

23

আমি ফিল্টার প্রয়োগ করার জন্য একটি জেনেরিক বিবৃতি বিকাশ করেছি:

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>;ছাড়াই নির্ধারিত if। যে showAllযদি ফিল্টার স্ট্রিং খালি সত্য।
অ্যান্ড্রু

দুর্দান্ত ধারণা কারণ এই ক্ষেত্রে আমরা ডেটা উত্সের ধরণের সাথে আবদ্ধ নই। বা কোনও ডেটা টেবিল।
মিশকুরভ

পুরোপুরি কাজ এবং অনুসন্ধান যুক্তিবিজ্ঞান আরও উন্নত করার জন্য আমরা dataGridView3.Rows যদি শর্ত হতে [u] ব্যবহার .Cells [4] .Value.ToString () indexOf ( "ফিল্টার STRING")> = 0 প্রতিস্থাপন করতে পারেন।
আলী আলী

1

আপনি আপনার ডেটা উত্স থেকে ডেটাভিউ অবজেক্ট তৈরি করতে পারেন । এটি আপনাকে সরাসরি ডেটাসোর্স পরিবর্তন না করে আপনার ডেটা ফিল্টার এবং বাছাই করতে দেয়।

এছাড়াও, dataGridView1.DataBind();আপনি ডেটা উত্স সেট করার পরে কল করতে মনে রাখবেন ।


4
তোমার উত্তরের জন্য ধন্যবাদ. হ্যাঁ, ডেটাভিউ অবজেক্ট তৈরি করা যেতে পারে, তবে এটি ডাটাসোর্সের ধরণের পরিবর্তন করে, দয়া করে শেষ কোডটি দেখুন। আমি আগের পোস্টে কেন এড়াতে চাইছি তার কারণটি আমি সংশোধন করেছি। ডেটাগ্রিডভিউ 1. ডেটাবাইন্ড () পদ্ধতিটি উইনফোর্ডসে বিদ্যমান নেই, আমি মনে করি এটি এএসপি থেকে এসেছে।
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

একটি ডেটাগ্রিডভিউতে স্বয়ংক্রিয় অনুসন্ধানের জন্য আমার কাছে একটি পরিষ্কার প্রস্তাব রয়েছে

এটি একটি উদাহরণ

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);
        }
    }


-2

আমি এই সমস্যাটি সমাধানের একটি সহজ উপায় খুঁজে পেয়েছি। বাইন্ডিং ডেটাগ্রিডভিউতে আপনি সবে করেছেন:datagridview.DataSource = dataSetName.Tables["TableName"];

আপনি যদি কোড পছন্দ করেন:

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

ডেটাগ্রিডভিউ ফিল্টার করার সময় আর কখনও ডেটা লোড করবে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.