Reputation: 4807
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.
Upvotes: 2
Views: 9951
Reputation: 22435
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
Upvotes: 6
Reputation: 540
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;
}
}
Upvotes: 2
Reputation: 6304
private void newBtn_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
var buttonNumber = button.Name.Remove(0, 6);
MessageBox.Show("Hello" + buttonNumber);
}
Upvotes: 1
Reputation: 149
newBtn.Click += new RoutedEventHandler((s,e) => MessageBox.Show("hallo"+((Button)s).Name);
Upvotes: 1
Reputation: 2140
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.
Upvotes: 1