c# Событие или "много много items"

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Spot, 30 Mar 2013.

  1. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    Приветствую,

    вообщем нужно создать бАльшое множество всяких кнопок и других айтемов, при клике на которые, что то будет происходить.
    Не хочется писать для каждой кнопочки отдельный обработчик событий, хотелось бы сделать один универсальный, который будет реагировать на клик в определённом родительском контроле, и уже сам решать, на какую кнопку кликнули и что должно произойти.

    Я в поиске более элегантного решения, чем то которое я состряпал на скорую руку.

    Code:
     private void groupBox1_Enter(object sender, EventArgs e)
            {
                int c_x = 0;
                int c_y = 0;
                Point koo = new Point();
                
                var my_groupbox = sender as GroupBox;
               koo =  my_groupbox.PointToClient(new Point(0,0));
                c_x = koo.X < 0 ? koo.X * -1 : koo.X;
                c_y = koo.Y < 0 ? koo.Y * -1 : koo.Y;
                c_x = Cursor.Position.X - c_x ;
                c_y = Cursor.Position.Y - c_y;
                string gets = my_groupbox.GetChildAtPoint(new Point(c_x, c_y)).ToString();
                MessageBox.Show(""+gets);
                
            }
    
    Щас буду перетворять ещё пару задумок в жизнь, посмотрим, что из этого выйдет. Тем не менее хотелось бы увидеть более красивое решение.

    ЗЫ. Вопрос:

    1. Столкнулся с трабом, что когда вешаю событие на групбокс и нажимаю на ожин из элементов внутри него - событие срабатывает только один раз. После чего можно тыкать до бесконечности - нету отклика.
    Зыто если сначала выделить один из эелементов в групбоксе, а потом зажать кнопку переключения меджу табами, но через какое то время событие срабатывает (очень удивился и схватился за свой домашний бубен). И ещё интересная вещь, если повесить ещё один групбокс и на него тоже прилепить событие, то таже фигня, однако если нажимать поочередно на грурпбоксы, то все работает нормально. То есть жму группбокс 1 - срабатыва, потом 2 и на втором срабатывает, потом снова 1 и он тоже работает.


    Кто нибудь сталкивался? Я с этим контролом первый раз работаю. Может где то есть какой то флаг, который нужно обнулять?
     
    #1 Spot, 30 Mar 2013
    Last edited: 30 Mar 2013
  2. FunOfGun

    FunOfGun Elder - Старейшина

    Joined:
    5 Sep 2012
    Messages:
    388
    Likes Received:
    71
    Reputations:
    124
    У меня щас нет под рукой C#, но загляни в код формы(.design который), там как раз создаются и устанавливаются на форму все контролы. Что-то вроде:
    Code:
    var button1=new Button();
    button1.x=100;
    ...
    button1.Click+=Button1_Click;//вот как-то так клавише задается обработчик
    
    Суть в том, что бы создать массив кнопок, а потом им всем присвоить один обработчик. Если кнопки расположены в определенном порядке, который можно задать простыми формулами, то все это можно в одном цикле делать, а Text'ы брать из массива, например.
     
    2 people like this.
  3. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    Не не не, это один из первых вариантов от которого я отказался. Я не хочу присваивать каждой кнопки евент, пускай и вешая всё на один обработчик. Если была суть именно решить вопрос - то вариант бы подошёл (хотя наверное не совсем, так как нужно создавать не только кнопки, а совершенно разные айтемы). Но в первую очередь хочется "красивого" решения вопроса.

    И да - по поводу Groupbox вопрос остаётся открытым - почему срабатывает тольок при первом евенте, после чего евенты игнорятся.
     
  4. cygwin

    cygwin New Member

    Joined:
    21 Mar 2013
    Messages:
    5
    Likes Received:
    0
    Reputations:
    0
    массив типа component(или как он там) и присваивай всё одному обработчику ??? профит
     
  5. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    Поясни, не совсем понял, что ты имеешь ввиду.
     
  6. BlackIce

    BlackIce Elder - Старейшина

    Joined:
    10 Jan 2013
    Messages:
    100
    Likes Received:
    31
    Reputations:
    27
    Не очень знаком с шарпом, но в делфи есть такое понятие как sender, тоесть объект, который посылает сообщение/генерирует событие. Была подобная задача, так я просто отлавливал сендеры контролов и в зависимости кто послал выполнял определенные действия. К сожалению не могу утверждать, что способ Вам подойдет...
     
    1 person likes this.
  7. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    Тоже не в тему C#, но в Qt есть QSignalMapper м.б и в C# подобное есть...
     
  8. seosimf

    seosimf Member

    Joined:
    3 Mar 2011
    Messages:
    271
    Likes Received:
    44
    Reputations:
    6
    Spot подписывайся на Control.ControlAdded, затем в обработчике указываем обработчик Control.Click для добавляемого контрола. В object sender будет контрол, по которому кликнули, там уже можно через GetType или is формировать логику.
     
    #8 seosimf, 30 Mar 2013
    Last edited: 30 Mar 2013
    1 person likes this.
  9. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    mironich, с Qt не особо знаком, но надо будет посмотреть о чем речь сQSignalMapper

    BlackIce, seosimf
    Этот метод схож с тем, который предлагал FunOfGun - по прежнему каждому контролу прийдётся добавлят евент someControl.Click() хоть обработка будет вести через одно описаное событие, в котором будет уже разборка who is who. Вариант тоже рассматривал, однако, если обьекты группируются, напримео, через groupbox, то sender будет отдавать тоже только groupbox.
    var some_control = sender as my_groupbox;
    Если же пытаться расценивать as some_another_control, то получим null.

    P.S.
    seosimf, или я тебя не так понял? Что то насктолько идея захватила перепробывать разные методы, что уж и мозг замылился. (пожалуй отдохну до завтра)

    ЗЫ. Вопрос по поводу одноразового срабатывания евента для groupbox по прежнему актуален.
     
    1 person likes this.
  10. DeepBlue7

    DeepBlue7 Elder - Старейшина

    Joined:
    2 Jan 2009
    Messages:
    359
    Likes Received:
    50
    Reputations:
    12
    Собственно, не вижу проблемы :/.

    Code:
    private void Form1_Load(object sender, EventArgs e)
            {
                foreach (Control ctrl in groupBox1.Controls)
                {
                    ctrl.Click += new EventHandler(gb1_controls_click);
                }
            }
    
            private void gb1_controls_click(object sender, EventArgs e)
            {
                Control myControl = (Control)sender;
    
                if (sender is TextBox)
                {
                    MessageBox.Show("It's a textbox !");
                }
    
                if (sender is Label)
                {
                    MessageBox.Show("It's a label !");
                }
    
                MessageBox.Show(myControl.Name);
            }
    
     
    1 person likes this.
  11. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    Блин, либо я неправильно выражаю свою мысль, либо не все читают внимательно...
    То что ты предложил, уже предлагали двое товарищей выше, пусть и не совсем в той форме... Тоже нормальные вариант, но мне не хотелось бы присваивать каждому элементу в групбоксе клик-евент завязаный пусть и на один обработчик. Тогда отпадает смысл в групбоксе как таковом - зачем он будет нужен, только для локальной привязки координат каждого элемента (по сути это и его цель), но мне хотелось бы работать именно с parent-контролом, и уже от него получая инфу по child на какую кнопку или айтем был произведён клик.

    seosimf, FunOfGun, DeepBlue7
    вы предложили схожие методы подхода, но если отталкиваться все же от персонально повешанного евента на каждый контрол в отдельности.
    Всем спасибо за ваши варианты, я примерно так и представлял, черновой вариант был схожим как у дипблю7.

    Однако, по поводу работы с елементами расположеными на parent-контроля аля groupbox или panel.
    ЗЫ, просто интересно для себя.
     
Loading...