简体   繁体   中英

Adding items to a WPF DataGrid bound to an ObservableCollection with a custom mutator in MVVM C#

This will be easiest if I first explain my code structure, then try to ask my question.

I have a base class containing some simple properties. We will call this BaseClass . I then have several other classes that extend BaseClass . Let's call these SubClass1 , Subclass2 , and SubClass3 . Now I have this view model, and it contains this private member:

private ObservableCollection<BaseClass> objs = new ObservableCollection<BaseClass>();

The initializer of the view model contains something like this:

objs.Add(new SubClass1(attribute1, attribute2));
objs.Add(new SubClass3(attribute1, attribute2));
objs.Add(new SubClass1(attribute1, attribute2));
objs.Add(new SubClass2(attribute1, attribute2));

Now, in this case, I have 3 separate datagrids. I want all three to draw from objs , but I want one to show only objects of type SubClass1 , one to show only objects of type SubClass2 ,and the last to show only objects of type SubClass3 . I have successfully achieved this by creating a property for each as follows:

public ObservableCollection<SubClass1> SubClass1Objs
{
    get
    {
        ObservableCollection<SubClass1> subObjs = new ObseleCollection<SubClass1>();
        if (objs != null)
            foreach (BaseClass obj in objs)
                if(obj.GetType() == typeof(SubClass1))
                subObjs .Add((SubClass1)obj);
        return subObjs ;
    }
}

The other 2 are identical. I bind the ItemSource of each datagrid to their property. This all works.

The user can currently edit any item in the data grid and the changes are reflected in objs . However, if the user tries to add an item to the datagrid, the items are not added to objs, and rightly so; I have no mutators(setters) for my properties. This is where my issues is. I am having trouble coming up with what the mutators would look like to add a new object to the collection. Does any one have any ideas? Thanks!

Thanks to @user49104 I was able to figure it out. I will post the answer here for anyone else who needs it.

I changed the properties of my SubClass1 , SubClass2 , and SubClass3 Collections to have normal more normal accessors and mutators and created a private member for each:

private ObservableCollection<SubClass1> _SubClass1Objs ;

public ObservableCollection<SubClass1> SubClass1Objs {
        get { if (_SubClass1Objs== null) _SubClass1Objs = new ObservableCollection<SubClass1>(); return _SubClass1Objs; }
        set { if (_SubClass1Objs!= value) { _SubClass1Objs= value; RaisePropertyChanged("SubClass1Objs"); } } 
}

In the initializer of my view model, set the SubClass data :

SubClass1Objs= new ObservableCollection<SubClass1>();
    if (objs != null)
        foreach (BaseClass obj in objs.Where(c => c.GetType() == typeof(SubClass1)))
            SubClass1Objs.Add((SubClass1)card);;
SubClass1Objs.CollectionChanged += SubClass1Objs_CollectionChanged;

Then lastly, in the CollectionChanged event, I check through to make sure no objects have been added or deleted and fix up objs:

// Check if a card was added
foreach (SubClass1 obj in SubClass1Objs)
    if (!objs.Contains(obj))
        objs.Add(obj);

// Check if a card has been deleted
for (int i = 0; i < objs.Where(c => c.GetType() == typeof(SubClass1)).Count(); ++i)
{
    BaseClass obj = objs.Where(c => c.GetType() == typeof(SubClass1)).ElementAt(i);
    if (!SubClass1Objs.Contains(obj))
        objs.Remove(obj);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM