none
Массив кнопок. WPF. RRS feed

  • Вопрос

  • Здравствуйте! Недавно начал изучать VB. Вот возникли проблемы.

    Подскажите пожалуйста, как программно сделать массив кнопок размером, например, 7х6 и разместить их в определенном месте окна WPF? Я пытаюсь делать как написано в книжке, но программа ругается. Видимо синтаксис другой...

    Спасибо.

    • Перемещено Abolmasov Dmitry 4 июля 2011 г. 11:29 (От:Языки программирования)

Ответы

  • Так и надо - использовать марджин.

    В WPF не используются абсолютные координаты х и у.


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:50
  • Извините, С# пишу уже наверное рефлекторно :).

    Me.Controls.Add - это вы из ВинФорм взяли.

    Разместите на окне стакпанель, как я описал в предыдущем посте. Потом используйте someStackPanel.Children.Add(btn); Так будет правильнее. 


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:49
  • Масив из кнопок - это тоже, что и массив из чисел.

    Например для хранения можно использовать список:

     Dim buttons As New List(Of Button)

    Потом в этот список можно добавлять елементы:
    buttons.Add(myNewButton);
    А по индексу - в последствии обращаться к элементам списка.


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:49
  • 1. У вас на интерфейсе 42 кнопки... это что-то ужасное.

    Может нужно использовать какой-то выпадающий список, или как?

     

    2. Если все таки нужны кнопки - делайте тоже, о чем говорилось ранее, только в цикле.

    Dim buttons As New List(Of Button) - де-то на уровне класса
    Де-то на уровне создания кнопок, например в контсрукторе
    For index As Integer = 0 To 41
     Button btnClickMe = new Button();
      btnClickMe.Content = "Click Me" & index;
       btnClickMe.Name = "btnClickMe" & index;  
      btnClickMe.Click += new RoutedEventHandler(this.CallMeClick);
      someStackPanel.Children.Add(btnClickMe);
    
      buttons.Add(btnClickMe);
    Next
    3. Не забывайте отмечать ответы, которые вам помогли.


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа Abolmasov Dmitry 5 мая 2011 г. 4:07
  • 1. Я ничего не хочу вычитать. Я хочу программно добавить 42 кнопки. И не знаю как это сделать. Мне до конца не понятна логика язка VB WPF. Как это сделать? Как добавить эти кнопки, чтобы потом уже обращаться к ним? Я и спрашиваю, как мне добавить их...

     

    1. Вы создаете ПУСТОЙ список кнопок, а потом из него хотите вычитать кнопку.

    После создания пустого списка в цикле ему нужно добавлять сами  кнопки, а уж потом к ним обращаться. Посмотрите внимательнее на мой пример (жирная строчка - добавление кнопки в список):

    Де-то на уровне создания кнопок, например в контсрукторе
    For index As Integer = 0 To 41
     Button btnClickMe = new Button();
     btnClickMe.Content = "Click Me" & index;
      btnClickMe.Name = "btnClickMe" & index; 
     btnClickMe.Click += new RoutedEventHandler(this.CallMeClick);
     someStackPanel.Children.Add(btnClickMe);
    
     buttons.Add(btnClickMe);
    Next
    2. Извините, С# примеры ищу на автомате. Но никто же не мешает Вам поискать:
    http://www.codeproject.com/KB/WPF/Quick_WPf_MonthView_Cal-2.aspx


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:50
  • 1. Для обращения по имени нужно использовать не список а Dictionary, где ключем при добавлении будет служить имя кнопки.

    2. Не нужно ничего устанавливать в систему - просто откомпилируйте и запустите солюшин.

     

    3. Подучите основы.  Извините, но вопросов у вас - зашкаливает, а контрол не такой уж тривиальный. 

     


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:50
  • у вас должен быть отдельно создан обработчик событий

    Private Sub CallMeClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
      '... ваш код - sender это и есть нажатая кнопка
    End Sub
    
    . Я подозреваю, в коде у вас его просто нет.

     

     

     

     


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 19:14

Все ответы

  • Разместите здесь, как ругаеться программа.

    Далее - пример, где в методе GenerateControls() на форму добавляеться два елемента - кнопка и текстовое поле.

    Чтобы пример заработал, в дизайнере добавте на форму панель и назовите ее someStackPanel.

    В файл исходного кода скопируете следующий блок, поставте праильное пространоство имен и имя

    класса формы (чтобы оно совпадало с именами в вашем реальном проекте).

     

    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    
    namespace AddControlsDynamically
    {
     public partial class Window1 : Window
     {
      public void Window_Loaded(object sender, RoutedEventArgs e)
      {
       GenerateControls();
      }
      public void GenerateControls()
      {
       Button btnClickMe = new Button();
       btnClickMe.Content = "Click Me";
       btnClickMe.Name = "btnClickMe";
       btnClickMe.Click += new RoutedEventHandler(this.CallMeClick);
       someStackPanel.Children.Add(btnClickMe);
       TextBox txtNumber = new TextBox();
       txtNumber.Name = "txtNumber";
       txtNumber.Text = "1776";
       someStackPanel.Children.Add(txtNumber);
       someStackPanel.RegisterName(txtNumber.Name, txtNumber);
      }
      protected void CallMeClick(object sender, RoutedEventArgs e)
      {
       TextBox txtNumber = (TextBox) this.someStackPanel.FindName("txtNumber");
       string message = string.Format("The number is {0}", txtNumber.Text);
       MessageBox.Show(message);
      }
     }
    }
    

     


    Don't forget to mark the correct answer Blog
  • Мне пока ещё сложно переводить с одного языка на другой... Я неделю как засел за VB... До C мне ещё далеко... :)))

    Что там массив кнопок, я незнаю как программно добавить одну-то кнопку.

    Вот код:

    Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    
     Dim btn As New Button()
        btn.Content = "Кнопка"
        Me.Controls.Add(btn)
    
      End Sub

    Последнюю строчку а именно Me.Controls.Add(btn) он подчёркивает и пишет что controls не является членом WpfApplication1.MainWindow. Это в WPF... А в обычном VB всё работает и ничего не подчёркивает. Но меня интересует именно WPF.

    У меня Экспресс-выпуск Visual Basic 2010.

  • Извините, С# пишу уже наверное рефлекторно :).

    Me.Controls.Add - это вы из ВинФорм взяли.

    Разместите на окне стакпанель, как я описал в предыдущем посте. Потом используйте someStackPanel.Children.Add(btn); Так будет правильнее. 


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:49
  • Ок. Спасибо.

    Ещё вопрос. Как теперь сделать массив из кнопок?

  • Масив из кнопок - это тоже, что и массив из чисел.

    Например для хранения можно использовать список:

     Dim buttons As New List(Of Button)

    Потом в этот список можно добавлять елементы:
    buttons.Add(myNewButton);
    А по индексу - в последствии обращаться к элементам списка.


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:49
  • Спасибо. Теперь не могу разобраться как мне при помощи цикла добавить в этот список массив кнопок. Т.е. мне нужен массив с кнопками, который я добавлю на someStackPanel и у каждой кнопки будет свой порядковый номер, чтобы можно было манипулировать свойствми каждой кнопки... Пока я сделал это всё вручную, и очень сложно разбираться в коде с 42 кнопками. Цикл гораздо всё упростит... Вот не знаю как.






  • 1. У вас на интерфейсе 42 кнопки... это что-то ужасное.

    Может нужно использовать какой-то выпадающий список, или как?

     

    2. Если все таки нужны кнопки - делайте тоже, о чем говорилось ранее, только в цикле.

    Dim buttons As New List(Of Button) - де-то на уровне класса
    Де-то на уровне создания кнопок, например в контсрукторе
    For index As Integer = 0 To 41
     Button btnClickMe = new Button();
      btnClickMe.Content = "Click Me" & index;
       btnClickMe.Name = "btnClickMe" & index;  
      btnClickMe.Click += new RoutedEventHandler(this.CallMeClick);
      someStackPanel.Children.Add(btnClickMe);
    
      buttons.Add(btnClickMe);
    Next
    3. Не забывайте отмечать ответы, которые вам помогли.


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа Abolmasov Dmitry 5 мая 2011 г. 4:07
  • Я делаю календарь, потому что функционал стандартного календаря меня не устраивает. Вот поэтому столько кнопок.

    Всё равно не получается сделать. Вот мой код:

     Dim buttons As New List(Of Button)
    
        For i = 1 To 42
          StackPanel1.Children.Add(buttons(i))
        Next i

     

    Пишет. что индекс за пределами диапазона. Как объявить размер массива?

  • 1. Вы создаете ПУСТОЙ список кнопок, а потом из него хотите вычитать кнопку.

    После создания пустого списка в цикле ему нужно добавлять сами  кнопки, а уж потом к ним обращаться. Посмотритев нимательнее на мой пример.

    2. Посмотрите в интернете уже готовые реализации:

    http://www.codeproject.com/KB/WPF/WPFOutlookCalendar.aspx

    http://www.codeproject.com/KB/WPF/ExtendingWPFCalendar.aspx

    http://www.codeproject.com/KB/selection/CultureMonthCalendar.aspx

    И лучше скажите чего вам в стандартном не хватает. 


    Don't forget to mark the correct answer Blog
  • 1. Я ничего не хочу вычитать. Я хочу программно добавить 42 кнопки. И не знаю как это сделать. Мне до конца не понятна логика язка VB WPF. Как это сделать? Как добавить эти кнопки, чтобы потом уже обращаться к ним? Я и спрашиваю, как мне добавить их...

    2. Ваш пример всё-таки из  серии C#, а мне синтаксис этого языка знаком ещё менее чем VB... Поэтому я просто теряюсь.

    Что касается календаря, то меня не устраивает то, что я не знаю как, например, отметить в нём определённые дни определённым цветом. Поиск по базе MSDN ничего не дал для меня... Я видел примеры на C#, но на VB я не знаю как сделать то же самое... Ваши ссылки демонстрируют прекрасные примеры, которые мне пригодились бы. НО я не знаю как реализовать это в Visual Basic. А все Ваши примеры на языке C. Если бы Вы мне смогли помочь, я был бы премного благдарен...  Но ещё раз повторяю, всё что не является языком Visual Basic -  для меня очень сложно...


  • 1. Я ничего не хочу вычитать. Я хочу программно добавить 42 кнопки. И не знаю как это сделать. Мне до конца не понятна логика язка VB WPF. Как это сделать? Как добавить эти кнопки, чтобы потом уже обращаться к ним? Я и спрашиваю, как мне добавить их...

     

    1. Вы создаете ПУСТОЙ список кнопок, а потом из него хотите вычитать кнопку.

    После создания пустого списка в цикле ему нужно добавлять сами  кнопки, а уж потом к ним обращаться. Посмотрите внимательнее на мой пример (жирная строчка - добавление кнопки в список):

    Де-то на уровне создания кнопок, например в контсрукторе
    For index As Integer = 0 To 41
     Button btnClickMe = new Button();
     btnClickMe.Content = "Click Me" & index;
      btnClickMe.Name = "btnClickMe" & index; 
     btnClickMe.Click += new RoutedEventHandler(this.CallMeClick);
     someStackPanel.Children.Add(btnClickMe);
    
     buttons.Add(btnClickMe);
    Next
    2. Извините, С# примеры ищу на автомате. Но никто же не мешает Вам поискать:
    http://www.codeproject.com/KB/WPF/Quick_WPf_MonthView_Cal-2.aspx


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:50
  • Не работает! Толи я чего-то не понимаю, то ли отличие языка VB от того кода, который Вы пишите, вносит свои коррективы.

    Вот я пытался перевести это на VB:

    For index As Integer = 0 To 41
    
          Dim btnClickMe As New List(Of Button)
    
          btnClickMe.Content = "Click Me" & index
          btnClickMe.Name = "btnClickMe" & index
          StackPanel1.Children.Add(btnClickMe)
          buttons.Add(btnClickMe)
    
    Next
    

    В итоге он подчёркивает btnClickMe.Content, btnClickMe.Name и Add(btnClickMe). А buttons требует объявить, считая это видимо переменной.

  • О, я вроде бы разобрался!

    Вот что вышло:

    For index As Integer = 0 To 41
    
          Dim btnClickMe As New Button()
          btnClickMe.Content = "Click Me" & index
          btnClickMe.Name = "btnClickMe" & index
          StackPanel1.Children.Add(btnClickMe)
    
    Next
    
  • Подскажите ещё. Как в WPF задать положение кнопки по X и Y координатам? Ничего кроме Margin я не нашел.

  • Так и надо - использовать марджин.

    В WPF не используются абсолютные координаты х и у.


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:50
  • Ок. Допустим я решил создать календарь, который будет встроен в основное окно. Я хочу добавить кноки программно, причем сделать так чтобы кнопки располагались квадратом 7х7. Что мне лучше всего использовать в качестве родительской основы? StackPanel почему-то располагает элементы только вертикально или только горизонтально. Т.е. кнопки получаются либо в столбик, либо в линию. Как расположить их по двум осям X и Y? Может быть Grid?


  • Да.

    Помоему вы и так уже наизвращались, поэтому советовал бы оставить 42 кнопки и использовать для них один обработчик.

    Это коряво но поверьте, автодобавление 42 кнопок на форму не сделает код более элегантным.

    Еще раз обращаю ваше внимание на http://www.codeproject.com/KB/WPF/Quick_WPf_MonthView_Cal-2.aspx


    Don't forget to mark the correct answer Blog
  • Да, спасибо. Я пытался разобраться с этим примером по ссылке, но пока мне сложно. Я так понимаю, что "Quick and Simple WPF Month-view Calendar" нужно как-то установить в систему и затем уже делать с ним манипуляции. Может подскажете как его установить?

    Что касается корявого кода. Вот я наваял таой код:

    Dim myGrid As New Grid()
        myGrid.Height = StackPanel1.Height
        myGrid.Width = StackPanel1.Width
        For i = 0 To 6
          Dim col As New ColumnDefinition()
          col.Name = "col" & i
          myGrid.ColumnDefinitions.Add(col)
          Dim row As New RowDefinition
          row.Name = "row" & i
          myGrid.RowDefinitions.Add(row)
        Next
        Dim num As Integer = 1
        For c = 0 To 5
          For index As Integer = 0 To 6
            Dim btnClickMe As New Button()
            btnClickMe.Content = index + num
            btnClickMe.Name = "btnClickMe" & index + num
            Grid.SetRow(btnClickMe, c)
            Grid.SetColumn(btnClickMe, index)
            myGrid.Children.Add(btnClickMe)
          Next
          num = num + 7
        Next
    StackPanel1.Children.Add(myGrid)
    

    Чем этот код плох, с точки зрения элегантности? Он работает и создаёт 42 кнопки как мне нужно. Теперь я не знаю как добраться до свойств каждой кнопки. Мне нужно редактировать каждую кнопку отдельно. Это возможно?

  • Как обратиться к кнопке по индексу нашел! :)) Спасибо! Я это сделал так:

     buttons(24).Background = Brushes.Red

     Но можно ли обратиться к кнопке по имени, а не по индексу?

    P.S. Был бы благодарен, если бы Вы мне помогли с установкой стороннего календаря...



  • 1. Для обращения по имени нужно использовать не список а Dictionary, где ключем при добавлении будет служить имя кнопки.

    2. Не нужно ничего устанавливать в систему - просто откомпилируйте и запустите солюшин.

     

    3. Подучите основы.  Извините, но вопросов у вас - зашкаливает, а контрол не такой уж тривиальный. 

     


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 9:50
  • Простите, если доставил неудобства... По VB я прочитал несколько книжек, но в голове не умещается столько технической информации. Я гуманитарий по образованию, поэтому мне сложно... Кроме того, книжки не дают ответы на все вопросы. Захотелось сделать более сложные вещи, чем то что описано в книжках, а спросить не у кого... Как сделать собственный календарь, в тех книгах что я читал, увы не написано. Приходится включать воображение и выдумывать. Но знаний не хватает для осуществления задуманного. Поэтому я сюда обращаюсь.

    P.S. За подсказку по Dictionary спасибо! Всё заработало!


  • Здравствуйте, пожалуйста, не забывайте отмечать ответы, решающие первоначальную проблему. Для этого под каждым сообщением есть кнопка 'Пометить как ответ'. Спасибо.


    Для связи [mail]
  • Хорошо, Дмитрий, постараюсь не забывать отмечать.

    Подскажите ещё пожалуйста. Как теперь присвоить созданной програмно кнопке обработчик событий? На С# это выглядит так:

    btnClickMe.Click += new RoutedEventHandler(this.CallMeClick);
    
    

    Но Visual Basic этот код не принимает. В частности подчёркивает Click и this.CallMeClick. Может тоже нужно хранить обработчик событий в Dictionary а затем вызывать его по имени кнопки? Но как его туда добавить?

    Спасибо.

  • у вас должен быть отдельно создан обработчик событий

    Private Sub CallMeClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
      '... ваш код - sender это и есть нажатая кнопка
    End Sub
    
    . Я подозреваю, в коде у вас его просто нет.

     

     

     

     


    Don't forget to mark the correct answer Blog
    • Помечено в качестве ответа MIchaelBourkanov 5 мая 2011 г. 19:14
  • Спасибо Вам огромное!