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.

+2


source to share


3 answers


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.

+1


source


In case sender property (button) .DataContext will be set to ItemsSource. If you want some control that is related to Sender in some way, use the VisualTreeHelper.



0


source


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));
        }
    }
}

      

0


source







All Articles