2

I made code that creates buttons dynamically, but how to assign different function to each button?

for (int i = 0; i < Buttons.Count; i++)
{
            Button newBtn = new Button();
            newBtn.Content = Buttons[i];
            newBtn.Name = "Button" + i.ToString();
            newBtn.Height = 23;
            stackPanel1.Children.Add(newBtn);
            newBtn.Click += new RoutedEventHandler(newBtn_Click);
}

private void newBtn_Click(object sender, RoutedEventArgs e)
{
        MessageBox.Show("Hello");
}

Now each button shows "Hello", but I wish it to be "Hello1", "Hello2"....ect.

0

5 Answers 5

6

if you could create a collection of objects with DelegateCommands or RelayCommand Property and DisplayName Property - you would just need a ItemsControl bind to this Collection and a DataTemplate for binding a button to Command and Text.

EDIT: just out of my head

 public class MyCommandWrapper
 {
    public ICommand Command {get;set;}
    public string DisplayName {get;set;}
 }

in your viewmodel

 public ObservableCollection<MyCommandWrapper> MyCommands {get;set;}

 MyCommands.Add(new MyCommandWrapper(){Command = MyTestCommand1, DisplayName = "Test 1"};
 ...

in your xaml

  <ItemsControl ItemsSource="{Binding MyCommands}">
   <ItemsControl.Resources>
     <DataTemplate DataType="{x:Type local:MyCommandWrapper}">
       <Button Content="{Binding DisplayName}" Command="{Binding Command}"/>
     </DataTemplate>
   </ItemsControl.Resources>
  </ItemsControl>

EDIT 2: if you need a new dynamic button - just add a new wrapper to your collection

Sign up to request clarification or add additional context in comments.

Comments

2
  for (int i = 0; i < Buttons.Count; i++)
    {
                Button newBtn = new Button();
                newBtn.Content = Buttons[i];
                newBtn.Height = 23;
                newBtn.Tag=i;
                stackPanel1.Children.Add(newBtn);
                newBtn.Click += new RoutedEventHandler(newBtn_Click);
    }

private void newBtn_Click(object sender, RoutedEventArgs e)
{
       Button btn=sender as Button;
       int i=(int)btn.Tag;

       switch(i)
       {
         case 0:  /*do something*/ break;
         case 1:  /*do something else*/ break;
         default: /*do something by default*/ break;
       }
}

Comments

1

Check the sender parameter of your newBtn_Click function. It should contain the instance of the button that was clicked. You can cast it to a button and check the name:

private void newBtn_Click(object sender, RoutedEventArgs e)
{
    var btn = sender as Button;
    if(btn != null)
    {
        MessageBox.Show(btn.Name);
    }
}

If you don't want to check the Name property, you can also use the Tag property (http://msdn.microsoft.com/library/system.windows.frameworkelement.tag.aspx) to which you can assign an arbitrary object and check this later:

Button newBtn = new Button();
newBtn.Tag = i;

And later in the click handler:

private void newBtn_Click(object sender, RoutedEventArgs e)
{
    var btn = sender as Button;
    if(btn != null)
    {
        if(btn.Tag is int)
            MessageBox.Show(String.Format("Hello{0}", btn.Tag));
    }
}

I would prefer the solution with Tag because it's more safe than extracting something from a string.

Comments

1
newBtn.Click += new RoutedEventHandler((s,e) => MessageBox.Show("hallo"+((Button)s).Name);

Comments

1
private void newBtn_Click(object sender, RoutedEventArgs e)
{
        var button = sender as Button;
        var buttonNumber = button.Name.Remove(0, 6);

        MessageBox.Show("Hello" + buttonNumber);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.