Adding to ObservableCollection
本文关键字:ObservableCollection to Adding | 更新日期: 2023-09-27 18:14:40
如果我在一个页面中有一个observablecollection,它在listview中插入项目。我如何从不同的窗口(类)添加到相同的observablecollection(listview) ?我不想使用INotifyPropertyChanged和所有这些。我所要做的就是添加一个项目到现有的列表视图。我什么都试过了,可就是不明白。请任何帮助是感激的。
CampersPage……(BindingCamper就是我说new ObservableCollection()
的方式 public partial class CampersPage : Page
{
MainWindow _parentForm;
public GridViewColumnHeader currentColumnSorted = null;
private SortAdorner currentAdorner = null;
String request1;
String request2;
String request3;
String request4;
// public ObservableCollection<Camper> Campers { get; private set; }
public CampersPage(MainWindow parent)
{
_parentForm = parent;
InitializeComponent();
_parentForm.bindings = new BindingCamper();
for (int i = 0; i < _parentForm.allCampers.Count; i++)
{
if (_parentForm.allCampers[i].getRequest(1) != null && _parentForm.allCampers[i].getRequest(2) != null && _parentForm.allCampers[i].getRequest(3) != null && _parentForm.allCampers[i].getRequest(4) != null)
{
request1 = _parentForm.allCampers[i].getRequest(1).getName();
request2 = _parentForm.allCampers[i].getRequest(2).getName();
request3 = _parentForm.allCampers[i].getRequest(3).getName();
request4 = _parentForm.allCampers[i].getRequest(4).getName();
}
_parentForm.bindings.Campers.Add(new Camper { FirstName = "" + _parentForm.allCampers[i].getFirstName(), LastName = "" + _parentForm.allCampers[i].getLastName(), Ages = _parentForm.allCampers[i].getAge(), SchoolGrade = _parentForm.allCampers[i].getGrade(), Gender = "" + _parentForm.allCampers[i].getGender(), bindingRequest1 = request1, bindingRequest2 = request2, bindingRequest3 = request3, bindingRequest4 = request4 });
//DataContext = _parentForm.bindings;
}
DataContext = _parentForm.bindings;
}
——现在我点击一个按钮,出现一个新窗口,我想在CampersPage的列表视图中添加一个新的露营者。
public partial class AddNewCamper : Window
{
MainWindow _parentForm;
public AddNewCamper(MainWindow parentForm)
{
InitializeComponent();
_parentForm = parentForm;
// _parentForm.bindings = new BindingCamper();
}private void btnSubmitNewCamper_Click(object sender, RoutedEventArgs e)
{
String firstName = txtNewFirstName.Text;
String lastName = txtLastName.Text;
int age;
int grade;
String newage = comboNewAge.Text;
if (firstName != "" && lastName != "" && IsNumber(txtNewGrade.Text) && newage != "")
{
age = Convert.ToInt16(newage);
grade = Convert.ToInt16(txtNewGrade.Text);
// Create New Camper
Camper person = new Camper(age, grade, boxNewGender.Text, firstName, lastName);
_parentForm.allCampers.Add(person);
//This is just adding the camper to the listview. Not sure if it is actually adding it to the database.
_parentForm.bindings.Campers.Add(new Camper { FirstName = person.getFirstName(), LastName = person.getLastName(), Ages = person.getAge(), SchoolGrade = person.getGrade() });
//CampersPage p = new CampersPage(_parentForm);
DataContext = _parentForm.bindings;
我是否必须以某种方式将AddNewCamper的命名空间添加到xaml中的CampersPage的命名空间?
<ListView HorizontalAlignment="Stretch" Margin="0,12" x:Name ="listViewCampers" ItemsSource="{Binding Campers}" DisplayMemberPath="bindMe" IsSynchronizedWithCurrentItem="True" Grid.Column="1">
ObservableCollection类:
public partial class BindingCamper
{ // This class assist in binding campers from listview to the textboxes on the camperspage
public ObservableCollection<Camper> Campers { get; set; }
public ObservableCollection<Staff> StaffMembers { get; set; }
public ObservableCollection<Schedule> schedule { get; set; }
public ObservableCollection<Group> Groups { get; set; }
public BindingCamper()
{
Campers = new ObservableCollection<Camper>();
StaffMembers = new ObservableCollection<Staff>();
schedule = new ObservableCollection<Schedule>();
Groups = new ObservableCollection<Group>();
}
我不会说你用错了WPF,但是你确实让你的生活变得很困难。我建议阅读一下MVVM模式——它确实使WPF开发更容易(这里是很好的入门文章)。
你现在使用的方法在几个层面上是不正确的:
- 你的窗口/页面需要对彼此有太多的了解才能正常工作
- 的结果,是依赖于父窗体在你的子窗口(而你真正需要的是依赖于窗口上下文,这实际上是露营者列表)
- 你需要做太多的手动通知/设置来实现你的目标(而WPF有很好的工具来自动完成)
- 您似乎通过视图(
MainWindow
)暴露了模型(allCampers
)
所有这些都可以通过重新设计来解决:
- 您的视图(主要,CampersPage, AddNewCamper)应该依赖于
BindingCamper
类(本质上可以是他们的视图模型),而不是彼此 - 相同的
BindingCamper
实例应该被设置为DataContext
所有 - 你不应该手动添加绑定(就像你现在做的);所有这些都可以(也应该)在XAML 中完成
CampersPage
类应该是这样的:
public partial class CampersPage : Page
{
public CampersPage(BindingCamper camper)
{
InitializeComponent();
DataContext = camper;
}
}
它不应该初始化父窗口的数据并设置它的绑定。这是完全错误的。
实际上,这种方法(通过构造函数提供数据上下文)可以在所有视图类中使用(可能也包括AddNewCamper
和MainWindow
)。
现在,当你需要露营者页面,比如说从你的主窗口,它变得很容易:
public partial class MainWindow : Window
{
public void ShowCampers()
{
var campersPage = new CampersPage((BindingCampers) this.DataContext);
// show campersPage
}
}
与AddNewCamper
window相同。给它传递数据上下文。当您添加新的露营者时,将其添加到BindingCamper.Campers
列表(可通过数据上下文获得):
// rest of the btnSubmitNewCamper_Click method elided
Camper person = new Camper(age, grade, boxNewGender.Text, firstName, lastName);
((BindingCamper)this.DataContext).Campers.Add(person);
。由于数据绑定和可观察集合的组合机制,这个新元素将在MainWindow
和CampersPage
中立即可见。
从数据库中获取露营者的代码应该是带有某种DAO对象的包装(作为DAL的一部分-我知道,有很多丑陋的流行词,但幸运的是它们都是相关的,而且相当明显)。例如,您可以有一个类来处理从数据库: 获取露营者。
public class CampersProvider
{
public IEnumerable<Camper> GetAllCampers()
{
// here you put all your code for DB interaction
// and simply return campers
}
}
为了给你一个快速的解决方案,你可以再次将CampersProvider
传递给MainWindow
的构造函数,调用GetAllCampters
的方法并为BindingCamper
构建可观察集合。然而,这不是非常MVVM的方法。这些东西通常由视图模型(另一个独立的类)处理,目前还没有。你发布的代码需要相当多的工作,我认为这不会是一个坏主意,如果你读了一点关于MVVM模式,并尝试将其应用到你的应用程序。