添加到ObservableCollection

时间:2011-11-16 05:33:28

标签: c# wpf visual-studio observablecollection

如果我在列表视图中插入项目的页面中有observablecollection。如何从不同的窗口(类)添加相同的observablecollection(listview)?我不想使用INotifyPropertyChanged等等。我要做的就是在现有的listview中添加一个项目。我已经尝试了一切,我无法弄明白。请任何帮助表示赞赏。

CampersPage ...(BindingCamper只是我的方式基本上说新的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的listview中添加一个新的露营者。

      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>();

   }

1 个答案:

答案 0 :(得分:4)

我不会声称你使用WPF错误,但你肯定会让你的生活变得困难。我建议稍微阅读 MVVM 模式 - 它确实使WPF开发变得更容易(这里是一个很好的起点article)。

目前使用的方法在几个层面上都不正确:

  • 您的窗口/页面需要有太多关于彼此才能正常工作的知识
  • 结果是,在您的子窗口中依赖于父窗体(而您真正需要的是依赖窗口上下文,实际上是露营者列表
  • 你需要做太多的手动通知/设置来实现你的目标(而WPF有很好的工具来自动完成)
  • 您似乎通过视图(allCampers)公开模型(MainWindow

所有这些都可以通过一些重新设计来解决:

  1. 您的观点(Main,CampersPage,AddNewCamper)应该依赖于BindingCamper类(基本上可以是它们的视图模型),而不是彼此
  2. BindingCamper的同一个实例应设置为DataContext所有
  3. 不应该手动添加绑定(就像您现在正在做的那样);所有可以(并且应该)从XAML
  4. 完成

    考虑到上述情况,您的CampersPage课程应如下所示:

    public partial class CampersPage : Page
    {
        public CampersPage(BindingCamper camper)
        {
            InitializeComponent();
            DataContext = camper;
        }
    }
    

    它绝不应初始化父窗口的数据并设置它的绑定。这是完全错误的。

    实际上,这种方法(通过构造函数提供数据上下文)可以在所有视图类中使用(可能是AddNewCamperMainWindow)。

    现在,当你需要露营者页面时,从你的主窗口说,它变得非常简单:

    public partial class MainWindow : Window
    {
        public void ShowCampers()
        {
            var campersPage = new CampersPage((BindingCampers) this.DataContext);
            // show campersPage
        }
    }
    

    AddNewCamper窗口相同。只需传递数据上下文。添加新露营车时,请将其添加到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);
    

    这就是全部。由于数据绑定和可观察集合的组合机制,这个新元素将立即在MainWindowCampersPage中可见。

    修改

    从数据库中获取露营者的代码应该包含某种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模式并尝试将其应用于您的应用程序,这将不是一个坏主意。