DataGridView - AutoComplete - fragmenty

0

Witam.

Próbuję zrobić coś takiego :
0b0b4e0c6d.png

Czyli:
DataGridView i chcę aby po wpisaniu jakiegoś ciągu jednej z kolumn pokazało "podpowiedzi" które będą wynikiem zapytania w stylu
string.Format("SELECT nazwa FROM tabela WHERE nazwa LIKE '%{0}%'", CellValue.Replace(' ', '%')).

Źródło AutoComplete uzupełniam w taki sposób:

        private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {           
                TextBox autoText = e.Control as TextBox;
                if (autoText != null)
                {
                    SqlCommand SQLCmd = new SqlCommand("SELECT nazwa FROM tabela ", SQLC);
                    SqlDataReader SQLDR = SQLCmd.ExecuteReader();
                    AutoCompleteStringCollection DataCollection = new AutoCompleteStringCollection();
                    while (SQLDR.Read())
                    {
                        DataCollection.Add(SQLDR[0].ToString());
                    }
                    SQLDR.Close();
                    autoText.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    autoText.AutoCompleteSource = AutoCompleteSource.CustomSource;   
                    autoText.AutoCompleteCustomSource = DataCollection;                    
                }          
        }

Jednak nie mam pomysłu jak przekonać go wyszukiwania po fragmentach tekstu a nie od początku.

0

Ty chcesz pobrać wszystkie dane z bazy i odfiltrować je w GUI?

0

W sumie to bez znaczenia czy pobiorę wszystkie rekordy z bazy i odfiltruje w kliencie, czy pobiorę już odfiltrowane.
Chodzi mi o to że jak mam na przykład taki zestaw:
Młotek Zielony
Młotek Czerwony
Młotek Czarny

to żeby po wpisaniu :
mło zi
zwróciło:
Młotek Zielony

a po wpisaniu
mło cz
zwróciło
Młotek Czerwony
Młotek Czarny

0

To jest bez znaczenia, jeśli danych albo użytkowników aplikacji jest bardzo mało. Niemniej jednak i tak chyba najłatwiej zrobić to jakimś full text searchem po stronie bazy. Jeśli chcesz robić po stronie klienta, to sam będziesz musiał napisać algorytm przeszukujący wszystkie rekordy i zwracający je z Twoimi wymaganiami - domyślne zachowanie autocomplete nie umożliwia tego, co chcesz osiągnać.

0

To jeszcze muszę nauczyć się jak można "podmienić" to standardowe działanie na własne ;)

Jednak muszę poprosić o pomoc... możecie mi powiedzieć jak się do tego zabrać / czego szukać ?

0

Panowie (i nieliczne Panie ;) ) czy ja dobrze kombinuje ?
Musze stworzyć klasę pochodną po TextBox i w niej zmodyfikować sposób w jaki tworzona jest lista podpowiedzi ?
Jeżeli tak to gdzie tego szukać ?
Będzie to jakaś metoda klasy TextBox lub TextBoxBase ?

0

Może coś w ten deseń trochę robione metodą kamienia łupanego ale może się przyda ;p

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AutoCompleteDataGridView
{
    public partial class Form1 : Form
    {
        BazaFirmaEntities b;
        Rectangle r;
        int rowIndex = -1;
        int columnIndex = -1;
        TextBox tb;

        public Form1()
        {
            InitializeComponent();

            b = new BazaFirmaEntities();

            dataGridView1.ColumnCount = 3;
            dataGridView1.Columns[0].Name = "Lp";
            dataGridView1.Columns[1].Name = "R";
            dataGridView1.Columns[2].Name = "Nazwa";

            this.listBox1.Height = 0;
            this.listBox1.Visible = false;
        }

        private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            r = this.dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
            this.listBox1.Location = new Point(r.X,r.Y+2*r.Height);
            rowIndex = e.RowIndex;
            columnIndex = e.ColumnIndex;
            if (columnIndex != 2) this.listBox1.Visible = false;
        }

        private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            try
            {
                if (dataGridView1.CurrentCell.ColumnIndex == 2)
                {
                    tb = (TextBox)e.Control;
                    tb.TextChanged += tb_TextChanged;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void tb_TextChanged(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentCell.ColumnIndex != 2) return;
            this.listBox1.Items.Clear();
            string tmp1 = tb.Text.Split()[0].Trim();
            string tmp2 = tmp1;

            if (tb.Text.Split().Count() > 1 && tb.Text.Split()[1] != "")
               tmp2 = tb.Text.Split()[1];

            var w = (from l in b.EMP
                     where l.Nazwa.ToUpper().Contains(tmp1.ToUpper()) &&
                           l.Nazwa.ToUpper().Contains(tmp2.ToUpper())
                     select l.Nazwa).ToArray();

            if (w.Count() > 0)
            {
                listBox1.Height = 200;
                this.listBox1.Visible = true;
            }
            this.listBox1.Items.AddRange(w);
        }

        private void listBox1_Click(object sender, EventArgs e)
        {
            this.dataGridView1[columnIndex, rowIndex].Value = this.listBox1.SelectedItem.ToString();
            this.listBox1.Items.Clear();
            this.listBox1.Hide();
        }
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1