简体   繁体   English

在XAML中使用动态名称创建WPF按钮

[英]Creating a WPF button with a dynamic name in XAML

I have a bound ListBox in WPF where each item has an up / down button to move the item up or down in the list box. 我在WPF中有一个绑定的ListBox,其中每个项目都有一个向上/向下按钮,可以在列表框中向上或向下移动该项目。

However I need to know which button fired the event so I want to set the name of the button to "UpButton" + listBoxItem.Text type of thing. 但是我需要知道哪个按钮触发了事件,所以我想将按钮的名称设置为“ UpButton” + listBoxItem.Text类型的东西。

Here's a simplified version of the XAML 这是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 somebody knows of a control out there that provides similar sorting functionality and / or with DragDrop to sort it, I'd appreciate any help as I'm about 2 hours overdue for heading off on holiday. 如果有人知道那里的控件可以提供类似的排序功能,并且/或者可以通过DragDrop对其进行排序,那么我将不胜感激,因为我打算在假期前逾时2小时。

As gimalay said, in the Click event handler, you can get the associated item from the sender's data context (as it part of the data template). 正如gimalay所说,在Click事件处理程序中,您可以从发送者的数据上下文中获取关联的项目(作为数据模板的一部分)。

Button senderButton = sender as Button;
var item = senderButton.DataContext;

Joseph's suggestion would be an overkill for a simple problem like this. 约瑟夫的建议对于这样一个简单的问题可能是过大了。

In the event handler Sender(button).DataContext property will be set to ItemsSource item. 在事件处理程序中,Sender(button).DataContext属性将设置为ItemsSource项目。 If you want get some control, that somehow related to Sender, use VisualTreeHelper. 如果要获得某种与发件人有关的控件,请使用VisualTreeHelper。

Like Yacoder said, there is definitely a more elegant way to do this. 就像Yacoder所说的那样, 绝对有一种更优雅的方法。 If, however, you want to go with the dynamic name approach, you should be able to make it work using an attached property like so: 但是,如果您想使用动态名称方法,则应该能够使用如下所示的附加属性使其起作用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM