Creating a dynamic named WPF button in XAML
I have a linked ListBox in WPF where each item has an up / down button to move the item up or down in the list.
However, I need to know which button triggered the event, so I want to set the button's name to "UpButton" + listBoxItem.Text.
Here's a simplified version of the XAML
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=Position}"/>
<Label Grid.Column="1" Content="{Binding Path=Name}" FontSize="18" Margin="0,10,0,0" />
<WrapPanel Grid.Column="2" >
<Button Click="MoveUpClick" Name="UpButton">Up</Button>
<Button Click="MoveDownClick" Name="DownButton">Down</Button>
</WrapPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If anyone knows of a control that provides a similar sorting function and / or with DragDrop for sorting, I would be grateful for any help as I will be 2 hours late to go on vacation.
source to share
As gimalay said, in your Click event handler, you can get the associated element from the sender data context (as part of the data template).
Button senderButton = sender as Button;
var item = senderButton.DataContext;
Joseph's suggestion would be overkill for such a simple problem.
source to share
As Yacoder said, there is definitely a more elegant way to do this. If, however, you want to use the dynamic name approach, you have to get it to work using the attached property, for example:
namespace ListBoxExample
{
public static class TagAttach
{
public static readonly System.Windows.DependencyProperty TagProperty =
System.Windows.DependencyProperty.RegisterAttached(
"Tag", typeof (string), typeof (TagAttach));
public static void SetTag(System.Windows.UIElement element, string value)
{
element.SetValue(TagProperty, value);
}
public static string GetTag(System.Windows.UIElement element)
{
return (string)element.GetValue(TagProperty);
}
}
}
<Window x:Class="ListBoxExample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:ListBoxExample"
Title="Window1" Height="300" Width="300">
<Grid>
<ListBox ItemsSource="{Binding}" Grid.IsSharedSizeScope="True">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A" />
<ColumnDefinition SharedSizeGroup="B" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Position}"/>
<Label Grid.Column="1" Content="{Binding Name}" FontSize="18" Margin="0,10,0,0" />
<WrapPanel Grid.Column="2" >
<Button Click="MoveUpClick" loc:TagAttach.Tag="{Binding Name}">Up</Button>
<Button Click="MoveDownClick" loc:TagAttach.Tag="{Binding Name}">Down</Button>
</WrapPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
namespace ListBoxExample
{
public partial class Window1
{
public Window1()
{
InitializeComponent();
DataContext = new[]
{
new {Name = "Tom", Position = "Butcher"},
new {Name = "Dick", Position = "Baker"},
new {Name = "Harry", Position = "Candlestick Maker"}
};
}
private void MoveUpClick(object sender, System.Windows.RoutedEventArgs e)
{
System.Windows.MessageBox.Show("Up - " + TagAttach.GetTag(sender as System.Windows.UIElement));
}
private void MoveDownClick(object sender, System.Windows.RoutedEventArgs e)
{
System.Windows.MessageBox.Show("Down - " + TagAttach.GetTag(sender as System.Windows.UIElement));
}
}
}
source to share