从Code-Behind操作ViewModel中的集合

时间:2015-10-12 14:46:51

标签: c# xaml gridview windows-8.1 windows-10

我的模特:

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"));
        }
    }

我的CollectionViewSource:

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

我的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>

我的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;
}

我的代码隐藏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
}

我已经尝试过此操作,但收到错误0xC0000005: Access violation reading location 0x00000004.并将其重定向到vm.AddNew(item);行。所有这些代码都已由@Bells更新/指导。

1 个答案:

答案 0 :(得分:1)

每次将新项目添加到集合中时,您将重新组合项目并重置源。这将导致网格视图重置其位置。为了保持位置,您必须最初将一个源集合指定为ItemsSource,并且应该对同一集合进行操作。

    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" />