C#使用动态文本框/按钮/网格删除行

时间:2015-06-15 11:20:21

标签: c# wpf button dynamic textbox

我已经测试过一些想法使用动态文本框和按钮,向网格添加项目效果非常好,但如果我想删除它有一些错误,有时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>

谢谢你, Tkay

2 个答案:

答案 0 :(得分:1)

当项目数量发生变化时,WPF的ItemsControl是在视图中显示项目的正确方法。

许多控件都继承自ItemsControl,例如ComboBox本身,DataGridListBox ......但在此示例中,我将使用{{ 1}}直接,因为你要做的事情不需要任何额外的功能。

首先, XAML

ItemsControl

我已将“ - ”按钮和TextBox的定义放在ItemTemplate中。对于我们添加到其中的每个项目, <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> 将重复使用此模板。

现在,代码隐藏

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); } } 处理,您只需要ItemsControlAdd个项目。

我为Remove的项目使用了自定义类(Item),但它可能是您想要的任何内容。在这种情况下,Item的定义只是:

ItemsControl

检查我在public class Item { public int Id { get; set; } } 方法中使用Delete_OnClick属性来检索当前的Item实例。

那是因为当你向DataContext添加一个对象时,它会用它的可视化表示(我们在模板中定义,在这种情况下)创建相应的“可视项目”,并分配添加的对象作为此“可视项目”的DataContext和控件。这样你就可以直接创建Bindings到它的属性等等。

答案 1 :(得分:0)

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

但是回答你原来的问题......发生的事情是你从RowDefinition删除了Grid,但是你没有更新其余控件的Grid.Row属性相应

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

如果您删除自己创建的其中一行,Grid现在只有4行定义,但您的“+”按钮仍然分配给Grid.Row 4(不存在) )。因此,它被置于最接近的匹配,Grid.Row数字3.它不会消失,它恰好位于第3行的“ - ”按钮下。