Doubt about how to position buttons

1

Images are for illustration only.

What I need to do, is this:

  • There are several buttons with their respective names, and can be called (clicked).

  • I type the name of that button in the search game field and the rest of the buttons disappear. Being the only one I typed.

  • Does anyone know how I can do this?

        
    asked by anonymous 03.05.2017 / 02:50

    2 answers

    5

    Demonstration of working code:

    Yourquestionisverysimpleanditisveryeasytodevelopasolutionforthisthatyouneed.

    I'llgiveyouabase,thealgorithmpracticallydone,you'llneedtoadaptsomethingsandgiveanimprovementaswell.Therearealotthatcanbeimproved,thelimitisyourimagination.

    Well,let'stakethesteps.

    About"preparation"

  • Create a panel to place these buttons for games. If you use FlowLayoutPanel the elements will always be repositioned from left to right (see the second image of the next item). This will make it easier to find them and will also allow you to separate your screen into different pieces. In my example, the panel is named mainPanel .

  • Set (on all buttons) how each of them will be identified as a given game. In the example, I used the property Tag to set this and left the Text property for display only (note that some buttons show short names, but the search works for the actual game name).

    Thedashedpartisthepanel.Inthenextimage,thepropertiestab,lookatthevaluesofthepropertiesTextandTagofthelastbuttonofthefirstrow.

    TheinterestingthingaboutusingtheTagpropertyistobeabletousetheactualgamenametodothesearch,buttoshowthebuttononlyitsabbreviation.Forexample:

  • Definewhenthesearchwilltakeplace.Intheexample,IdefinedthatthesearchwouldoccurwhenevertheusertypedsomethingintheTextBoxfetch,usingtheevent TextChanged .

  • About the code

  • At form initialization (in the constructor, after the InitializeComponents() method), you must create a list with all the buttons that exist inside the main panel. This will allow you to remove the buttons from the panel without losing them, because of course it will be necessary to put them there again.
  • Now comes the part that does the work, the implementation of the TextChanged event. The algorithm is simple and naive.

  • A filter is made in the _todosBotoes variable (the one that was created at form initialization) using Linq, this filter looks for buttons whose Tag property is a text and contains the text that was typed by the user. I still gave a crafted one and caused the search to be done by the property Text , only if < Tag property% is null or can not be converted to string .

  • All controls on the main panel are removed.

  • The controls returned by the filter are added in the main panel.

  • Notice that I used a method called ContainsIgnoreCase() . This method does not exist in class string , is an extension method created based on the algorithm of this response and serves so that the comparison treats tiny and upper-case characters as the same.

  • Follow the code

    public partial class Form1 : Form
    {
        private readonly Button[] _todosBotoes;
        public Form1()
        {
            InitializeComponent();
            // Passo 1
            _todosBotoes = mainPanel.Controls.OfType<Button>().ToArray();
        }
    
        private void txtBusca_TextChanged(object sender, EventArgs e)
        {
            // Passo 2.1
            var controles = _todosBotoes.Where(bt => (bt.Tag as string ?? bt.Text).ContainsIgnoreCase(txtBusca.Text))
                                        .ToArray();
    
            // Passo 2.2
            mainPanel.Controls.Clear();
    
            // Passo 2.3
            mainPanel.Controls.AddRange(controles);
        }
    }
    

    Method code ContainsIgnoreCase()

    public static bool ContainsIgnoreCase(this string source, string search)
    {
        return source.IndexOf(search, StringComparison.CurrentCultureIgnoreCase) >= 0;
    }
    
        
    03.05.2017 / 15:55
    2

    Given that you have a database (in the code simulated by games), put a flowLayoutPanel in your Form, a Search TextBox, and a timer that triggers the search, can be in a range of 500ms for example. The TextChanged event of the TextBox restarts the timer.

    Follow the code:

        private DataTable dtJogos()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("nome");
            DataRow r = dt.NewRow();
            r["nome"] = "Diablo";
            dt.Rows.Add(r);
            r = dt.NewRow();
            r["nome"] = "Need For Speed";
            dt.Rows.Add(r);
            r = dt.NewRow();
            r["nome"] = "GTA";
            dt.Rows.Add(r);
            r = dt.NewRow();
            r["nome"] = "GRID";
            dt.Rows.Add(r);
            r = dt.NewRow();
            r["nome"] = "DIRT";
            dt.Rows.Add(r);
            r = dt.NewRow();
            r["nome"] = "Exemplo";
            dt.Rows.Add(r);
            return dt;
        }
    
        private void MontarBotoes()
        {
            flowLayoutPanel1.Controls.Clear();
            DataTable dt = dtJogos();
    
            DataRow[] rows = dt.Select("nome LIKE '" + textBoxPesquisa.Text + "%'");
    
            foreach (DataRow r in rows)
            {
                Button b = new Button();
                b.Name = r["nome"].ToString();
                b.Text = b.Name;
                b.Size = new System.Drawing.Size(150, 32);
                b.Parent = flowLayoutPanel1;
                b.Click += b_Click;
                b.Show();
            }
        }
    
        void b_Click(object sender, EventArgs e)
        {
            string nome = ((Button)sender).Name;
            //Processao Clique no botão do jogo
            MessageBox.Show("Você clicou no jogo: " + nome);
        }
    
        private void timerPesquisa_Tick(object sender, EventArgs e)
        {
            timerPesquisa.Enabled = false;
            MontarBotoes();
        }
    
        private void textBoxPesquisa_TextChanged(object sender, EventArgs e)
        {
            timerPesquisa.Enabled = false;
            timerPesquisa.Enabled = true;
        }
    
        
    03.05.2017 / 16:01