UWP C# 如何处理动态创建的按钮和控件的事件

UWP C# How To Handle Event for Dynamically Created Button(s) and Control

关于 post 我还有其他问题

  1. 如何控制这些动态创建的按钮事件?例如。按钮 1 打开 LED 1,按钮 2 打开 LED 2 等
  2. 如何有选择地删除按钮并重新组织其余按钮,中间没有空格。

谢谢。

更新: 我有一个例程来添加客户端的详细信息,例如来自客户端的 client IP 等,并在 scrollviewer 中添加和显示它们。 我如何 link clientnameclient ip 到字典?

private async void AddClientList()
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            ClientListUserControl clientListControl = new ClientListUserControl(this, new ClientList(clientName, receiveIP, DateTime.Now, receivePort, receiveService, receiveDEV, receiveSTS, receiveACT));
            ClientList_Panel.Children.Add(clientListControl);
            clientListControl.updateDisplay();
        });
    }

第一个问题:
要处理这个问题,您应该引入一个字典,其中按钮是键,您的值是客户端。这样就可以在ClickHandler中获取链接的客户端了。

public Dictionary<Button, object> clientDict = new Dictionary<Button, object>();

注意:这里client的类型是object,因为不知道你是什么类型!

您将按钮添加到 AddButton 例程中。再一次:我不知道你从哪里得到你的客户,所以我添加了值 null。更改此项以满足您的要求。然后添加另一个 ClickHandler 并获取链接的客户端:

 b.Click += HandleButtonClick;
 clientDict.Add(b, null);



 private void HandleButtonClick(object sender, RoutedEventArgs e)
        {
            //Execute whatever you want from your client:
            var client = clientDict[sender as Button];
        }

第二个问题:
您需要添加一个 RemoveMethod,从中获取应删除的按钮的列和行。之后您可以操作所有其他按钮的列和行 属性。为避免新添加的按钮与其他按钮不对齐,您需要更改添加过程,使新按钮的位置取决于字典中元素的数量。这里有一个完整代码的示例:

public int buttonCounter = 1;
public Dictionary<Button, object> clientDict = new Dictionary<Button, object>();

private void RemoveBtn(Button button)
{
    var row = Grid.GetRow(button);
    var column = Grid.GetColumn(button);

    //Rearange
    foreach (var btn in clientDict.Keys)
    {
        var r = Grid.GetRow(btn);
        var c = Grid.GetColumn(btn);

        if (c > column || (c == column && r > row))
        {
            if (r != 0)
            {
                //Set the row new
                Grid.SetRow(btn, r - 1);
            }
            else
            {
                //Need to set it to a new column
                Grid.SetRow(btn, 3);
                Grid.SetColumn(btn, c - 1);
            }
        }
    }
    myGrid.Children.Remove(button);
    clientDict.Remove(button);
}

private void Button_Click(object sender, RoutedEventArgs e)
{

    //Create the button
    Button b = new Button();
    b.Height = 30;
    b.Width = 100;
    b.VerticalAlignment = VerticalAlignment.Top;
    b.HorizontalAlignment = HorizontalAlignment.Left;
    b.Margin = new Thickness(20, 20, 0, 0);
    b.Content = "Button " + buttonCounter;
    b.Click += HandleButtonClick;
    clientDict.Add(b, null);

    //Calculate the place of the button
    int column = (int)(clientDict.Count / 4);
    int row = clientDict.Count % 4;

    //Check if you need to add a columns
    if (row == 0 && myGrid.ColumnDefinitions.Count <= column)
    {
        ColumnDefinition col = new ColumnDefinition();
        col.Width = new GridLength(column, GridUnitType.Auto);
        myGrid.ColumnDefinitions.Add(col);
    }

    //Add the button
    myGrid.Children.Add(b);
    Grid.SetColumn(b, column);
    Grid.SetRow(b, row);
    buttonCounter++;
}

private void HandleButtonClick(object sender, RoutedEventArgs e)
{
    //Execute whatever you want from you handler:
    var client = clientDict[sender as Button];
}

注意:重新排列过程未进行性能优化。

也可以使用Button的Tag属性来传递参数。此属性继承自FrameworkElement,一般用于获取或设置任意对象值,可用于存储该对象的自定义信息。

请参考以下代码

    private void ButtonCreateNewButton_Click(object sender, RoutedEventArgs e)
    {
        Button b = new Button();
        b.Height = 30;
        b.Width = 100;
        b.VerticalAlignment = VerticalAlignment.Top;
        b.HorizontalAlignment = HorizontalAlignment.Left;
        b.Margin = new Thickness(6, 6, 6, 6);
        b.Content = "Button " + buttonCounter;
        b.Tag = "LED-" + buttonCounter;
        b.Click += Button_Click;

        ....

        buttonCounter++;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var btn = sender as Button;
        var led = btn.Tag;
        //use led_name as a parameter here, according with this variable to turn on the LED
        TurnOnOffLed(led);
    }