提问人:Rembie01 提问时间:7/25/2022 最后编辑:Rembie01 更新时间:7/26/2022 访问量:67
将对象从子窗口传回 MainWindow
Passing an object back to MainWindow from a subwindow
问:
我正在尝试创建一个小数据库程序,您可以在其中添加、修改和删除新闻网站的文章。有一个带有 DataGrid 的 MainWindow 来显示所有文章。按下“添加”按钮后,将打开一个新窗口,供您编辑新创建的文章。或者可以按下修改按钮来编辑当前选择的文章。如何将文章传递回 MainWindow 以将其添加到 ObservableCollection/modify ObservableCollection?
public partial class MainWindow : Window
{
private int lastIdArtikel = 0;
private Artikel currentSelection = null;
private ObservableCollection<Artikel> ArtikelDatabase = new ObservableCollection<Artikel>();
private void Add_Click(object sender, RoutedEventArgs e)
{
Artikel nieuwArtikel = new Artikel(++lastIdArtikels);
ArtikelDatabase.Add(nieuwArtikel);
ArtikelVenster artikelVenster = new ArtikelVenster(ref nieuwArtikel);
artikelVenster.Show();
}
private void Modify_Click(object sender, RoutedEventArgs e)
{
try
{
ArtikelVenster artikelVenster = new ArtikelVenster(ref huidigeSelectie);
artikelVenster.Show();
}
catch (NullReferenceException exception)
{
Console.WriteLine(exception.StackTrace);
}
}
public partial class ArtikelVenster : Window
{
public Artikel artikel { get; private set; }
public int id { get; private set; }
public string title { get; private set; }
public object category { get; private set; }
public string nameJournalist { get; private set; }
public bool mayBePublished { get; private set; }
public bool isPublished { get; private set; }
public string content { get; private set; }
public int length { get; private set; }
public ArtikelVenster(ref Artikel huidigArtikel)
{
InitializeComponent();
artikel = huidigArtikel;
try
{
LaadData();
}
catch (NullReferenceException exception)
{
Console.WriteLine(exception.StackTrace);
}
CategorieBox.SelectedIndex = 2;
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
private void LaadData()
{
IdLabel.Content = artikel.id;
DatumLabel.Content = artikel.creationDate.ToString();
TitelBox.Text = artikel.title;
CategorieBox.SelectedItem = artikel.category;
NaamJournalistBox.Text = artikel.nameJournalist;
IsGepubliceerdToggle.IsChecked = artikel.isPublished;
MagGepubliceerdWordenToggle.IsChecked = artikel.mayBePublished;
if (artikel.content == null)
{
InhoudBox.Selection.Text = "";
}
else
{
InhoudBox.Selection.Text = artikel.content;
}
}
private void Confirm_Click(object sender, RoutedEventArgs e)
{
if (artikel == null)
{
Artikel nieuwArtikel = new Artikel(id);
nieuwArtikel.updateArtikel(title, category, nameJournalist, mayBePublished, isPublished, content, length);
artikel = nieuwArtikel;
}
else
{
artikel.updateArtikel(title, category, nameJournalist, mayBePublished, isPublished, content, length);
}
this.Close();
}
private void TitelBox_TextChanged(object sender, TextChangedEventArgs e)
{
title = TitelBox.Text;
}
private void CategorieBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
category = CategorieBox.SelectedItem;
}
private void NaamJournalistBox_TextChanged(object sender, TextChangedEventArgs e)
{
nameJournalist = NaamJournalistBox.Text;
}
}
public class Artikel
{
public int id { get; private set; }
public string title { get; private set; }
public object category { get; private set; }
public string nameJournalist { get; private set; }
public bool mayBePublished { get; private set; }
public bool isPublished { get; private set; }
public string content { get; private set; }
public int length { get; private set; }
public DateTime creationDate { get; private set; }
public Artikel(int id)
{
this.id = id;
this.creationDate = DateTime.Now;
}
public void updateArtikel(string title, object category, string nameJournalist, bool mayBePublished, bool isPublished, string content, int length)
{
this.title = title;
this.category = category;
this.nameJournalist = nameJournalist;
this.mayBePublished = mayBePublished;
this.isPublished = isPublished;
this.content = content;
this.length = length;
}
}
}
为了使其更具可读性,省略了某些部分。如果需要更多信息,请告诉我。
答:
1赞
yassinMi
7/26/2022
#1
在窗口类中声明事件
public event EventHandler<Artikel> Confirmed;
在确认按钮单击处理程序中调用它
//artikel being the object that you want to send back to the main window
Confirmed?.Invoke(this,artikel);
您可以从调用方添加侦听器:
artikelVenster.Confirmed+=(s, e) =>{//do something with e };
artikelVenster.Show();
评论
1赞
Mathieu Guindon
7/26/2022
按原样,这将需要 Artikel 继承 EventArgs,这可能不是一个好主意。最好创建一个专用的 ArtikelEventArgs 来封装 Artikel 引用。不过,整体方法在我看来不错:+1!
0赞
yassinMi
7/26/2022
这是框架本身的限制,还是只是更好的方法?因为当我使用任何类型时,我不会收到任何编译或运行时错误/警告
1赞
Mathieu Guindon
7/26/2022
啊,你是对的,没有强制继承的通用约束 - 但是是的,这完全是一种最佳实践:这样,如果/当处理程序需要任何其他信息时,事件的类型及其处理程序的签名不需要更改,只需将新成员添加到 EventArgs 派生的类中,您就完成了。TEventArgs
System.EventArgs
评论