#c# #wpf
#c# #wpf
Вопрос:
В настоящее время я работаю над следующим кодом.
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.Текст и tb.Text, потому что он еще не создан.
Может быть, у кого-то есть решение для меня. Или я делаю что-то подобное неправильно. Я довольно новичок в wpf и C #.
заранее благодарю вас!
Ответ №1:
Вам следует изучить MVVM и систему шаблонов WPF.
Когда у вас пользовательский интерфейс с повторением, вам следует подумать о itemscontrol. Привяжите itemssource к списку или observablecollection, где t — это viewmodel. Это имело бы общедоступные свойства для каждого атрибута в вещи, которую вы повторяете. Затем свяжите шаблон с t через datatype или просто используя свойство itemtemplate элемента itemscontrol.
Давайте вызовем t row viewmodel или rowvm. Это открыло бы общедоступное свойство icommand. Привяжите это к команде вашей кнопки, и когда вы нажимаете кнопку, срабатывает код, который у вас есть в команде. Это «знает» связанное значение Kandidaat, потому что это было бы общедоступным свойством в rowvm и, следовательно, это.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 и command.
Несколько простых и сложных примеров:
https://www.dotnetcurry.com/wpf/1160/wpf-itemscontrol-fundamentals-part1
Для того, чтобы выровнять столбцы идентификатора, кандидата и кнопок, вы могли бы использовать сетку со столбцами и общей областью размера. https://wpf.2000things.com/tag/issharedsizescope /
Или
Вы могли бы использовать gridview в listview, в котором есть встроенные столбцы.
Ответ №2:
Ваша проблема не показывает точно всю проблему. Было бы неплохо узнать, является ли это WPF? Формы Windows?
Я предполагаю, что spParijen — это таблица или сетка, которая заполняется данными tb и button. Это первоначальные вещи, которые я вижу, неверны, и все это связано с контекстом:
tBid, tb и button заполняются в контексте цикла foreach. Если бы эта коллекция была позже отображена, я бы предположил, что вы увидели пустой список. Это потому, что каждый объект, созданный в контексте этого цикла foreach, уничтожается, как только вы выходите из цикла, или вскоре после создания нового экземпляра, или очень скоро после. Единственная причина, по которой ваша кнопка не уничтожается, заключается в том, что у вас есть привязка к вашему коду делегирования щелчка.
Вторая проблема заключается в названии ваших трех переменных. Они не сообщают следующему разработчику, что на самом деле представляют эти поля. Я предполагаю, что кнопка представляет выбранного кандидата, поэтому назовите ее так.
Третья проблема заключается в том, что первая переменная (tBid) никогда не будет существовать, потому что она нигде не сохранена.
И, наконец, допустим, у вас есть 10 кандидатов. Итак, если бы ваш код работал, у вас был бы список из 10 кандидатов и 10 кнопок. Таким образом, ваш обработчик щелчков завершится ошибкой или (если они не были уничтожены) вы всегда будете обрабатывать последнего кандидата, которого вы добавили в список. Вам нужно, чтобы кнопка содержала что-то уникальное, чтобы вы могли найти содержимое кнопки и, следовательно, список, в котором находится каждое текстовое поле.
Я предлагаю заполнить дочерние элементы dr[«id»], dr[кандидат], button. Логика обработчика щелчков сначала преобразует отправителя в кнопку. Затем получите идентификатор с кнопки (вы могли бы сделать всплывающую подсказку идентификатором, если вы используете WPF). Затем выполните поиск в своих дочерних элементах, пока не найдете этот идентификатор. Теперь продолжайте свой процесс.