简体   繁体   中英

Manipulating Collection inside ViewModel from Code-Behind

My Model :

public class Cont: INotifyPropertyChanged
{ 

    private string _Contact;
    public string Contact
    {
        get { return _Contact; }
        set
        {
            _Contact= value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("Contact"));
        }
    }

    private string _Age;
    public string Age
    {
        get { return _Age; }
        set
        {
            _Age = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("Age"));
        }
    }

My CollectionViewSource:

<CollectionViewSource x:Key="group" Source="{Binding GroupedCollection}" ItemsPath="{Binding GroupedCollection[0].ContactColl}" IsSourceGrouped="True">
            </CollectionViewSource>

My GridView :

<GridView ItemsSource="{Binding Source={StaticResource group}}" 
          SelectionMode="None" ScrollViewer.VerticalScrollBarVisibility="Hidden">
            <GridView.GroupStyle>
                <GroupStyle HidesIfEmpty="True">
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock x:Name="keyHeader" Text="{Binding Key}"/>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </GridView.GroupStyle>
            <GridView.ItemTemplate>
                <DataTemplate>
                        <TextBlock Text="{Binding Contact}"/>
                </DataTemplate>
            </GridView.ItemTemplate>

        </GridView>

My ViewModel :

public class ContVM: INotifyPropertyChanged
{
    public ObservableCollection<Cont> Contlist = new ObservableCollection<Cont>();

    private ObservableCollection<ContItem> _GroupedCollection;
    public ObservableCollection<ContItem> GroupedCollection
    {
        get
        {
            if (_GroupedCollection == null)
            {
                _GroupedCollection= new ObservableCollection<ContItem>();
            }
            return _GroupedCollection;
        }
        set
        {
            _GroupedCollection = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("GroupedCollection"));
        }
    }

    public void SetInitialCollection()
    {
        var keyList = Contlist .GroupBy(c => c.Age).Select(g => g.Key);
        foreach (var key in keyList)
        {
            var contItem= new ContItem();
            contItem.Key = key;
            var contList = Contlist.Where(c => c.Age == key);
            foreach (var item in contList )
            {
                contItem.ContactColl.Add(item);
            }
            GroupedCollection.Add(contItem);
        }
    }

    public void AddNew(Cont Item)
    {
        var contItem = GroupedCollection.FirstOrDefault(g => g.Key == Item.Age );
        if ( contItem != null )
        {
            contItem.ContactColl.Add(Item);
        }
        else
        {
            contItem = new ContItem();
            contItem.Key = Item.Age ;
            GroupedCollection.Add(contItem);
        }
    }

    public void Delete(Cont Item)
    {
        var contItem = GroupedCollection.FirstOrDefault(g => g.Key == Item.Age);
        if (contItem != null)
        {
            if (contItem.ContactColl.Contains(Item))
            {
                contItem.ContactColl.Remove(Item);
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class ContItem : INotifyPropertyChanged
{
    public string Key { get; set; }

    private ObservableCollection<Cont> _ContactColl;
    public ObservableCollection<Cont> ContactColl
    {
        get
        {
            if (_ContactColl== null)
            {
                _ContactColl= new ObservableCollection<Cont>();
            }
            return _ContactColl;
        }
        set
        {
            _ContactColl= value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("ContactColl"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

My code-behind cs :

ContVM vm = new ContVM();

private void Add_new_cont_Click(object sender, RoutedEventArgs e)
{
    // a button that add a new data from 2 textbox
    Cont item = new Cont();
    item.Contact = textbox1.Text;
    item.Contact = textbox2.Text;

    vm.AddNew(item); // error line
}

Already tried this, but I get error 0xC0000005: Access violation reading location 0x00000004. and it redirect me at line which is vm.AddNew(item); . All these codes have been updated/guided by @Bells.

Each time when a new item is being added to the collection, you are regrouping the items and resetting the source. That will cause the grid view to reset its position. In order to maintain the position, you have to assign a source collection initially as the ItemsSource and manipulations should be done on the same collection.

    public class Cont
    {
        public string Contact { get; set; }
        public string Age { get; set; }
    }

    public class ContItem
    {
        public string Key { get; set; }

        private ObservableCollection<Cont> _contactColl;
        public ObservableCollection<Cont> ContactColl
        {
            get
            {
                if (_contactColl == null)
                    _contactColl = new ObservableCollection<Cont>();
                return _contactColl;
            }

        }
    }

    public class TestClass
    {
        public ObservableCollection<Cont> Contlist = new ObservableCollection<Cont>();
        private ObservableCollection<ContItem> _groupedCollection;
        public ObservableCollection<ContItem> GroupedCollection
        {
            get
            {
                if (_groupedCollection == null)
                    _groupedCollection = new ObservableCollection<ContItem>();
                return _groupedCollection;
            }
        }

        public void SetInitialCollection()
        {
            //Add the existing items in ContactList (if any) to a grouped collection.

            var keyList = Contlist.GroupBy(c => c.Age).Select(g => g.Key);
            foreach (var key in keyList)
            {
                var contItem = new ContItem();
                contItem.Key = key;
                var contList = Contlist.Where(c => c.Age == key);
                foreach (var item in contList)
                {
                    contItem.ContactColl.Add(item);
                }
                GroupedCollection.Add(contItem);
            }

        }

        public void AddNewItem()
        {
            var cont = new Cont();
            cont.Age = "32";
            cont.Contact = "";
            var contItem = GroupedCollection.FirstOrDefault(g => g.Key == cont.Age);
            if (contItem != null)
            {
                contItem.ContactColl.Add(cont);
            }
            else
            {
                contItem = new ContItem();
                contItem.Key = cont.Age;
                contItem.ContactColl.Add(cont);
                GroupedCollection.Add(contItem);
            }
        }

        public void DeleteItem(Cont cont)
        {
            var contItem = GroupedCollection.FirstOrDefault(g => g.Key == cont.Age);
            if (contItem != null)
            {
                if (contItem.ContactColl.Contains(cont))
                {
                    contItem.ContactColl.Remove(cont);
                }
            }
        }
    }


<CollectionViewSource x:Key="group" Source="{Binding GroupedCollection}"
                ItemsPath="ContactColl" IsSourceGrouped="True" />

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