C# 动态删除行 Textbox/Button/Grid
C# Delete Row with Dynamic Textbox/Button/Grid
我已经用动态文本框和按钮测试了一些想法,将项目添加到我的网格中效果很好,但是如果我想删除它会有一些错误,有时 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>
谢谢,
天凯
首先,我不得不请您考虑对此类内容使用 ItemsControl。它更容易和清洁。如果您不知道该怎么做,请告诉我,我会尝试 post 举个例子。
但是回答你最初的问题......发生的事情是你从 Grid
中删除 RowDefinition
,但你没有更新 Grid.Row
属性 其余控件相应。
例如,如果您创建了 3 行,那么您原来的“+”按钮现在位于 Grid.Row
数字 4 上。
如果删除您创建的行之一,Grid
现在只有 4 行定义,但您的“+”按钮仍分配给 Grid.Row
4(这不不存在)。因此,它被放在最接近的匹配上,Grid.Row
数字 3。它没有消失,它就在第 3 行的“-”按钮的正下方。
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>
我已将您对“-”按钮和文本框的定义放入 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
处理,您只需要 Add
和 Remove
项 to/from 它。
我为 ItemsControl
的项目使用了自定义 class(项目),但它可以是您想要的任何东西。在这种情况下,Item 的定义就是:
public class Item
{
public int Id { get; set; }
}
检查我在 Delete_OnClick
方法中使用 DataContext
属性 检索当前 Item 实例。
那是因为当您将对象添加到 ItemsControl
时,它会创建相应的 "visual item" 及其可视化表示(在本例中,我们已在模板中定义),并分配作为此 "visual item" 和控件的 DataContext 添加的对象。这样你就可以直接创建绑定到它的属性等。
我已经用动态文本框和按钮测试了一些想法,将项目添加到我的网格中效果很好,但是如果我想删除它会有一些错误,有时 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>
谢谢, 天凯
首先,我不得不请您考虑对此类内容使用 ItemsControl。它更容易和清洁。如果您不知道该怎么做,请告诉我,我会尝试 post 举个例子。
但是回答你最初的问题......发生的事情是你从 Grid
中删除 RowDefinition
,但你没有更新 Grid.Row
属性 其余控件相应。
例如,如果您创建了 3 行,那么您原来的“+”按钮现在位于 Grid.Row
数字 4 上。
如果删除您创建的行之一,Grid
现在只有 4 行定义,但您的“+”按钮仍分配给 Grid.Row
4(这不不存在)。因此,它被放在最接近的匹配上,Grid.Row
数字 3。它没有消失,它就在第 3 行的“-”按钮的正下方。
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>
我已将您对“-”按钮和文本框的定义放入 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
处理,您只需要 Add
和 Remove
项 to/from 它。
我为 ItemsControl
的项目使用了自定义 class(项目),但它可以是您想要的任何东西。在这种情况下,Item 的定义就是:
public class Item
{
public int Id { get; set; }
}
检查我在 Delete_OnClick
方法中使用 DataContext
属性 检索当前 Item 实例。
那是因为当您将对象添加到 ItemsControl
时,它会创建相应的 "visual item" 及其可视化表示(在本例中,我们已在模板中定义),并分配作为此 "visual item" 和控件的 DataContext 添加的对象。这样你就可以直接创建绑定到它的属性等。