UWP C# System.InvalidCastException

UWP C# System.InvalidCastException

我之前曾在 post 上询问过如何 。现在我在 button 旁边添加了额外的 image 以指示 客户端 连接状态 。我有 2 个 buttons,一个用于 add,另一个用于 delete buttonimage。单击后,将出现 menuflyout 到 select 相应的要删除的按钮。我的问题是我设法添加了状态 image 但是当点击 删除 button 时,menuflyout 遇到 exception 表示 System.InvalidCastException

我的代码如下; 请帮忙。 谢谢。

public Uri connectedUri = new Uri("ms-appx:///Assets/icon-connected.png");
public Uri disconnectedUri = new Uri("ms-appx:///Assets/icon-disconnected.png");

private void AddMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
    var item = sender as MenuFlyoutItem;
    var deviceName = item.Text;
    var deviceIP = item.Tag;

    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 = deviceName;   // "Button " + buttonCounter;
    b.Tag = deviceIP;
    b.Click += AddMenuButton_Click;


    Image stsImg = new Image();
    BitmapImage bitmapImage = new BitmapImage();
    //Uri connectedUri = new Uri("ms-appx:///Assets/icon-connected");
    //Uri disconnectedUri = new Uri("ms-appx:///Assets/icon-disconnected");
    bitmapImage.UriSource = connectedUri;
    stsImg.Source = bitmapImage;
    stsImg.Width = 20;
    stsImg.Height = 20;
    stsImg.VerticalAlignment = VerticalAlignment.Top;
    stsImg.HorizontalAlignment = HorizontalAlignment.Left;
    stsImg.Margin = new Thickness(130, 20, 0, 0);
    stsImg.Name = deviceName;
    stsImg.Tag = deviceIP;

    //Calculate the place of the button
    int column = (int)(buttonCounter / 4);
    int row = buttonCounter % 4;

    //Check if you need to add a columns
    if (row == 0)
    {
        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);

    myGrid.Children.Add(stsImg);
    Grid.SetColumn(stsImg, column);
    Grid.SetRow(stsImg, row);
    buttonCounter++;
}

private void RemoveButton_Click(object sender, RoutedEventArgs e)
{
    var menuFlyout = new MenuFlyout();

    try
    {
        foreach (Button btn in myGrid.Children)
        {
            var row = Grid.GetRow(btn);
            var col = Grid.GetColumn(btn);
            //ButtonRow.Add(btn.Content.ToString(), row.ToString());
            //ButtonCol.Add(btn.Content.ToString(), col.ToString());
            var menuFlyoutItem = new MenuFlyoutItem() { Name = btn.Tag.ToString(), Text = btn.Content.ToString() };
            menuFlyoutItem.Tag = btn.Content.ToString();
            menuFlyoutItem.Click += RemoveMenuFlyoutItem_Click;
            menuFlyout.Items.Add(menuFlyoutItem);
        }
        RemoveButton.Flyout = menuFlyout;
    }
    catch (Exception)
    {

    }
}

问题是 foreach:

foreach (Button btn in myGrid.Children)

当这样写时,它会尝试将 Grid 的所有 children 转换为 Button。这是不可能的,因为有些 children 不是按钮。但是你可以这样写循环:

foreach (Button btn in myGrid.Children.OfType<Button>())

OfType<T> LINQ 扩展方法将过滤可枚举的输入,仅过滤给定类型的那些项目。

myGrid 类型 Button 的所有 children 都是吗?

 foreach (Button btn in myGrid.Children)

没有,因为myGrid.Children.Add(stsImg);

当您尝试将 stsImg 作为 Button 获取时,您会遇到该异常,因为 stsImg 不是 Button.

类型

您只需过滤按钮。

foreach (Button btn in myGrid.Children.OfType<Button>()){
// do stuff
}