我目前正在处理以下代码。
public void CbParty_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
spPartijen.Children.Clear();
MySqlConnection conn = new MySqlConnection("Server=localhost; Database=imtenb; Uid=root; Pwd=");
conn.Open();
MySqlCommand command = conn.CreateCommand();
command.CommandText = "SELECT * FROM kandidaten WHERE partij='" + ((DataRowView)cbParty.SelectedItem)["naam"].ToString() + "' ";
MySqlDataReader reader = command.ExecuteReader();
DataTable dtData = new DataTable();
dtData.Load(reader);
MySqlDataAdapter da = new MySqlDataAdapter(command);
da.Fill(dtData);
foreach (DataRow dr in dtData.Rows)
{
TextBox tbId = new TextBox();
tbId.Text = dr["id"].ToString();
tbId.Name = "tbId";
TextBox tb = new TextBox();
tb.Text = dr["kandidaat"].ToString();
tb.Name = "tb";
Button button = new Button();
button.Content = "wijzigen";
button.Click += ChangeKandidaat_Click;
spPartijen.Children.Add(tb);
spPartijen.Children.Add(button);
}
}
public void ChangeKandidaat_Click(object sender, RoutedEventArgs e)
{
conn.ChangeKandidaat(tbId.Text, tb.Text, ((DataRowView)cbParty.SelectedItem)["naam"].ToString());
}
public void ChangeKandidaat(string id, string kandidaat, string partij)
{
try
{
conn.Open();
MySqlCommand command = conn.CreateCommand();
command.CommandText = "UPDATE kandidaten SET kandidaat='kandiddddaat' WHERE partij='@partij' and id='@id'";
command.Parameters.AddWithValue("@id", id);
command.Parameters.AddWithValue("@kandidaat", kandidaat);
command.Parameters.AddWithValue("@partij", partij);
command.ExecuteNonQuery();
MessageBox.Show("De informatie is succesvol gewijzigd");
}
catch (Exception)
{
MessageBox.Show("Er is iets mis gegaan met het toevoegen van je standpunt, probeer het opnieuw.");
}
conn.Close();
}
我的问题是ChangeKandidaat_Click无法看到tbId.Text和tb.Text,因为尚未创建。
也许有人对我有解决方案。还是我做错了这种事情。 我是wpf和C#的新手。
提前谢谢!
答案 0 :(得分:0)
您应该研究MVVM和WPF的模板系统。
当您的UI具有重复功能时,您应该考虑使用itemsControl。将itemsource绑定到List或observablecollection,其中t是视图模型。在您要重复的内容中,每个属性都具有公共属性。然后通过数据类型或仅使用itemscontrol的itemtemplate属性将模板与t关联。
我们将其称为行视图模型或rowvm。 这将公开一个公共的icommand属性。将其绑定到按钮的命令,然后单击按钮,将触发命令中包含的代码。之所以“知道” Kandidaat的关联值,是因为它将是rowvm中的公共属性,因此也就是this.Kandidaat。
Itemscontrol:
https://rachel53461.wordpress.com/2011/09/17/wpf-itemscontrol-example/
您可以为每个“行”定义一堆东西,而不只是一个按钮:
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
…..
<TextBlock Text="{Binding Id}" />
<TextBlock Text="{Binding Kandidaat}"
Grid.Column="1"/>
<Button
Grid.Column="2"
Content="DoSomething"
Command="{DoSomethingCommand}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
mvvm和itemscontrol的简单介绍:
https://social.technet.microsoft.com/wiki/contents/articles/32164.wpf-mvvm-step-by-step-2.aspx
那只是使用一个字符串作为rowvm,您需要一个具有Id,Kandidaat和命令属性的类。
一些简单到复杂的示例:
https://www.dotnetcurry.com/wpf/1160/wpf-itemscontrol-fundamentals-part1
为了排列id,kandidaat和按钮的列,您可以使用带有列和共享大小范围的网格。 https://wpf.2000things.com/tag/issharedsizescope/
或
您可以在具有内置列的列表视图中使用gridview。
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.listview?view=netframework-4.7.2
答案 1 :(得分:0)
您的问题未完全显示整个问题。很高兴知道这是WPF吗? Windows表格?
我假设spParijen是一个用tb和button数据填充的表或网格。这些是我看到的最初的东西是错误的,并且都在处理上下文:
tbId,tb和button在foreach循环的上下文中填充。如果以后显示该收藏集,我想您会看到一个空列表。这是因为一旦退出循环,或者在创建新实例后不久或之后不久,在该foreach循环上下文中创建的每个对象都会被销毁。您的按钮没有被破坏的唯一原因是因为您绑定了您的点击委托代码。
第二个问题是三个变量的名称。他们没有告诉下一个开发人员这些字段实际代表什么。我假设按钮代表所选的候选人,因此将其命名为。
第三个问题是,第一个变量(tbId)不会存在,因为它没有保存在任何地方。
最后,假设您有10位候选人。因此,如果您的代码有效,则将列出10个候选者和10个按钮。因此,您的点击处理程序将失败,或者(如果未将其销毁)您将始终处理您放入列表中的最后一个候选项。您需要按钮包含唯一的内容,以便您可以找到按钮的内容,从而找到每个文本框所在的列表。
我的建议是为孩子们添加dr [“ id”],dr [候选人],按钮。点击处理程序逻辑将首先将发送方转换为按钮。接下来,从按钮获取标识符(如果正在执行WPF,则可以使工具提示成为标识)。然后搜索您的孩子,直到找到该ID。现在继续您的过程。