【问题标题】:C# Delete Row with Dynamic Textbox/Button/GridC# 使用动态文本框/按钮/网格删除行
【发布时间】:2015-06-15 11:20:20
【问题描述】:

我已经用动态文本框和按钮测试了一些想法,将项目添加到我的网格效果很好,但是如果我想删除它有一些错误,有时 1 行是空的,我的添加按钮消失或我的程序崩溃.

我做错了什么或错过了什么?

C#代码:

    public MainWindow()
    {
        InitializeComponent();
    }

    int Numberic = 0;
    private void NewButton_Click(object sender, RoutedEventArgs e)
    {
        #region Row and Numberic
        Numberic++;
        RowDefinition ROW = new RowDefinition();
        GridLength Height = new GridLength(59);
        ROW.Height = Height;

        MainGrid.RowDefinitions.Add(ROW);
        #endregion

        #region Set new Button Location
        int ButtonLocation = Grid.GetRow(NewButton);
        Grid.SetRow(NewButton, ButtonLocation + 1);
        #endregion

        #region Create TextBox
        TextBox CreateTextBox = new TextBox();
        CreateTextBox.Name = "NewTextBox_" + Numberic;
        CreateTextBox.Width = 438;
        CreateTextBox.Height = 35;
        CreateTextBox.Margin = new Thickness(53, 12, 0, 0);
        CreateTextBox.HorizontalAlignment = HorizontalAlignment.Left;
        CreateTextBox.VerticalAlignment = VerticalAlignment.Top;

        CreateTextBox.FontSize = 15;
        CreateTextBox.HorizontalContentAlignment = HorizontalAlignment.Left;
        CreateTextBox.VerticalContentAlignment = VerticalAlignment.Center;

        MainGrid.Children.Add(CreateTextBox);
        Grid.SetRow(CreateTextBox ,ButtonLocation);
        #endregion

        #region Create Button
        Button CreateButton = new Button();
        CreateButton.Name = "NewButton_" + Numberic;
        CreateButton.Width = 35;
        CreateButton.Height = 35;
        CreateButton.Margin = new Thickness(12, 12, 0, 0);
        CreateButton.HorizontalAlignment = HorizontalAlignment.Left;
        CreateButton.VerticalAlignment = VerticalAlignment.Top;

        CreateButton.Content = "-";
        CreateButton.FontSize = 20;
        CreateButton.FontWeight = FontWeights.Bold;
        BrushConverter BC = new BrushConverter();
        CreateButton.Background = (Brush)BC.ConvertFrom("#FFDB0000");
        CreateButton.Foreground = Brushes.White;
        CreateButton.BorderBrush = Brushes.Transparent;

        CreateButton.Click += new RoutedEventHandler(Delete_OnClick);

        MainGrid.Children.Add(CreateButton);
        Grid.SetRow(CreateButton, ButtonLocation);
        #endregion
    }

    private void Delete_OnClick(object sender, RoutedEventArgs e)
    {
        Button SelectedButton = (Button)sender;
        int SelectedRow = Grid.GetRow(SelectedButton);

        string[] Number = SelectedButton.Name.Split('_');
        string TextBoxName = "NewTextBox" + "_" + Number[1];
        TextBox SelectedTextbox = (TextBox)LogicalTreeHelper.FindLogicalNode(MainGrid, TextBoxName);

        MainGrid.Children.Remove(SelectedTextbox);
        MainGrid.Children.Remove(SelectedButton);

        //Numberic--;
        MainGrid.RowDefinitions.RemoveAt(SelectedRow);
    }

XAML 代码:

<Grid Name="MainGrid" ShowGridLines="True" OpacityMask="Black" Background="#FFEDEDED">
    <Grid.RowDefinitions>
        <RowDefinition Height="59" />
    </Grid.RowDefinitions>
    <Button Content="+" Height="35" HorizontalAlignment="Left" Margin="12,12,0,0" Name="NewButton" VerticalAlignment="Top" Width="35" BorderBrush="{x:Null}" Foreground="White" Background="#FF727272" FontWeight="Bold" FontSize="20" Click="NewButton_Click" />
</Grid>

谢谢你, 好了

【问题讨论】:

  • 为什么以所有神圣的名义,您要动态添加/删除控件?考虑将您的控件包装在Grid 或其他一些容器 中,并在用户不需要看到它时将其Visibility 属性更改为Collapsed
  • 你的意思是我为什么要添加和删除行?我在想有一个无尽的添加系统会很好。
  • 我相信@MikeEason 的意思是你为什么像使用WinForms 一样使用WPF?。在 WPF 中,我们通常使用 XAML 和数据绑定,并且从后面的代码中手动添加 UI 元素。如果您使用过数据绑定,那么删除数据绑定Textbox/Grid 就像从集合中删除对象一样简单。

标签: c# wpf button dynamic textbox


【解决方案1】:

WPF 的 ItemsControl 是在项目数量可以更改时在视图中显示项目的正确方法。

许多控件都继承自ItemsControl,例如ComboBox 本身,或DataGrid,或ListBox...但在此示例中,我将直接使用ItemsControl,因为您是尝试做不需要任何额外的功能。

首先,XAML

    <Grid Name="MainGrid" OpacityMask="Black" Background="#FFEDEDED">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <ItemsControl x:Name="MyItemsControl">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Button Content="-" Height="35" HorizontalAlignment="Left" Margin="12,12,0,0" Name="NewButton" VerticalAlignment="Top" Width="35" BorderBrush="{x:Null}" Foreground="White" Background="#FFDB0000" FontWeight="Bold" FontSize="20" Click="Delete_OnClick" />
                        <TextBox Width="438" Height="35" Margin="6,12,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="15" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        <Button Grid.Row="1" Content="+" Height="35" HorizontalAlignment="Left" Margin="12,12,0,0" Name="NewButton" VerticalAlignment="Top" Width="35" BorderBrush="{x:Null}" Foreground="White" Background="#FF727272" FontWeight="Bold" FontSize="20" Click="NewButton_Click" />
    </Grid>

我已将您对“-”按钮和 TextBox 的定义放在 ItemTemplate 中。 ItemsControl 将为我们添加到其中的每个项目重复使用此模板。

现在,代码隐藏

public partial class MainWindow : Window
{
    int Numberic = 0;

    private void NewButton_Click(object sender, RoutedEventArgs e)
    {
        var item = new Item();
        item.Id = ++Numberic;
        MyItemsControl.Items.Add(item);
    }

    private void Delete_OnClick(object sender, RoutedEventArgs e)
    {
        Button SelectedButton = (Button)sender;
        var item = SelectedButton.DataContext;
        MyItemsControl.Items.Remove(item);
    }
}

如您所见,这比您以前的方法简单得多,也更简洁。大部分逻辑由ItemsControl 处理,您只需要将AddRemove 项传入/传出即可。

我为 ItemsControl 的项目使用了自定义类 (Item),但它可以是您想要的任何东西。在这种情况下,Item的定义就是:

public class Item
{
    public int Id { get; set; }
}

检查在Delete_OnClick 方法中我使用DataContext 属性来检索当前的Item 实例。

这是因为当您将对象添加到 ItemsControl 时,它会创建相应的“可视项”及其可视表示(在本例中,我们已在模板中定义),并将添加的对象分配为 DataContext这个“视觉项目”和控件。这样你就可以直接创建绑定到它的属性等。

【讨论】:

  • 下一步将使用 MVVM 和数据绑定:P 查找有关绑定的信息以及如何使用它们来填充您的 ItemsControl,为您的按钮设置命令(而不是使用 Click 事件)并连接您的 TextBlocks 和 TextBoxes 到实际数据。
  • 这工作得很好,就像你说的,它少了我的代码。感谢您帮助我,期待数据投标。 :)
  • 你推荐一个学习 C# WPF 的网站吗?以我的知识和糟糕的英语,我找不到关于数据绑定或命令的东西。也许我是盲人。
  • 我建议你从这里开始:wpftutorial.net/GettingStarted.html ;) 和这里的数据绑定:wpftutorial.net/DataBindingOverview.html
【解决方案2】:

首先,我觉得有必要请您考虑使用 ItemsControl 来处理这类东西。它更容易和更清洁。如果您不知道该怎么做,请告诉我,我会尝试发布示例。

但是回答您最初的问题...正在发生的事情是您正在从 Grid 中删除 RowDefinition,但您没有相应地更新其余控件的 Grid.Row 属性。

例如,如果您创建了 3 行,则原来的“+”按钮现在位于 Grid.Row 数字 4。

如果您删除已创建的行之一,Grid 现在只有 4 个行定义,但您的“+”按钮仍分配给 Grid.Row 4(不存在)。因此,它被放在最接近的匹配项上,Grid.Row 数字 3。它不会消失,它就在第 3 行的“-”按钮下方。

【讨论】:

  • 好的,现在我知道我的按钮在哪里了,但是我怎样才能正确地移动它们呢?而且我不了解 ItemsControl,如果您能看到一个示例,那就太好了,也许这对我有帮助。
  • 好的,我会用正确的方法在 WPF 中使用 ItemsControl 添加另一个答案 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多