简体   繁体   中英

Creating grouped gridview and binding Observable collection data after grouping but no INotifyProperty Change is affecting the grid?

I am trying to make a grouped gridview in Windows 8 application I have a class named book whose ObservableCollection I have made in my ViewModel class for that page. But I need to group the data when I am trying to group and bind the data on my codebind file of XAML and then binding there is no effect of INotifyProperty happening. Please suggest how can I achieve this in my VW?

Code Below:

Code Behind of XAML:

 protected override void LoadState(Object navigationParameter,
                                               Dictionary<String, Object> pageState)
        {
            MainViewModel booksList = new MainViewModel();
            var teamGroups = booksList.BooksDetail.GroupBy(team => team.BookCategory)
                                           .OrderBy(team => team.Key.ToString());

            this.groupedItemsViewSource.Source = teamGroups;
        }

View Model Class:

  #region BooksDetail Collection
        /// <summary>
        /// The <see cref="BooksDetail" /> BooksDetail
        /// </summary>
        public const string BooksDetailPropertyName = "BooksDetail";

        private ObservableCollection<Book> _booksDetailProperty = new ObservableCollection<Book>();

        /// <summary>
        /// Gets the BooksDetail property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<Book> BooksDetail
        {
            get
            {
                return _booksDetailProperty;
            }

            set
            {
                if (_booksDetailProperty == value)
                {
                    return;
                }

                _booksDetailProperty = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(BooksDetailPropertyName);
            }
        }
        #endregion

  public void GetBooksDetail()
        {

                try
                {
                    // Check if the code is in Design Mode or Running Mode
                    if (ViewModelBase.IsInDesignModeStatic)
                    {
                        // Created the object of main model class
                        DesignMainModel mainModel = new DesignMainModel();

                        // Call method to get list of books detail
                        this.BooksDetail = mainModel.GetBooksDetailData();
                    }
                    else
                    {
                        // Check for internet connectivity 
                        if (Utility.IsInternetAvailable())
                        {
                            //TODO: Write the logic to to implement in Running Mode
                            // Created the object of main model class
                            DesignMainModel mainModel = new DesignMainModel();

                            // Call method to get list of books detail
                            this.BooksDetail = mainModel.GetBooksDetailData();

                            // Group by data on Book Category
                            this.GroupByBookDetailsOnCategory();
                        }
                        else
                        {
                            // Display Error Message for No internet Connection available
                            util.ShowUserMessage(App.GeneralMessageResource.GetString("InternetConnectionErrorMessage"), App.GeneralMessageResource.GetString("InternetConnectionErrorCategory"));
                        }
                    }

                }
                catch (Exception ex)
                {
                    // Display the error
                    util.ShowUserMessage(ex.Message, App.GeneralMessageResource.GetString("GeneralErrorTitle"));
                }
            }
        }

Books Class:

   #region BookCategory Property
        /// <summary>
        /// The <see cref="BookCategory" /> property's name.
        /// </summary>
        public const string BookCategoryPropertyName = "BookCategory";

        /// <summary>
        /// The _book category property
        /// </summary>
        private string _bookCategoryProperty = string.Empty;

        /// <summary>
        /// Gets the BookCategory property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string BookCategory
        {
            get
            {
                return _bookCategoryProperty;
            }

            set
            {
                if (_bookCategoryProperty == value)
                {
                    return;
                }

                _bookCategoryProperty = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(BookCategoryPropertyName);
            }
        }
        #endregion

Changed as per the input: I have created an ObservableCollection of Tuple. But now when I am binding it to CollectionViewSource then no list is getting populated. Please refer the code below: Let me know where I am making mistake:

XAML:

<GridView Grid.Row="1" Margin="5,0,0,0" Grid.Column="1"
         x:Name="itemGridView"
         SelectionMode="Multiple"
         ItemTemplate="{StaticResource CategoryLists}"
         ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
           ItemContainerStyle="{StaticResource CategoryListsStyle}">
    <GridView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <Grid>
                                <StackPanel Orientation="Horizontal" Margin="15,0,0,0">
                                    <TextBlock Text="{Binding Key}" Margin="0,-5,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" FontFamily="Segoe UI Regular" Foreground="#00bfff" FontSize="27"/>
                                    <!--<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/>-->
                                </StackPanel>
                            </Grid>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <VariableSizedWrapGrid Orientation="Vertical" Margin="10,-1,35,0"/>
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </GridView.GroupStyle>

</Grid>

Property: #region BooksDetailGrouped Collection /// /// The property's name. /// public const string BooksDetailGroupedPropertyName = "BooksDetailGrouped";

        /// <summary>
        /// The _books detail grouped property
        /// </summary>
        private ObservableCollection<Tuple<string, ObservableCollection<Book>>> _booksDetailGroupedProperty = new ObservableCollection<Tuple<string, ObservableCollection<Book>>>();



        /// <summary>
        /// Gets the BooksDetailGrouped property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<Tuple<string, ObservableCollection<Book>>> BooksDetailGrouped
        {
            get
            {
                return _booksDetailGroupedProperty;
            }

            set
            {
                if (_booksDetailGroupedProperty == value)
                {
                    return;
                }

                _booksDetailGroupedProperty = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(BooksDetailGroupedPropertyName);
            }
        }
        #endregion

Method to group:

// Grouping the data
            var booksGroup = this.BooksDetail.GroupBy(books => books.BookCategory)
                                            .OrderBy(books => books.Key.ToString());

            // Convert grouped data to ObservableCollection<Tuple<string, ObservableCollection<Book>>>
            this.BooksDetailGrouped = new ObservableCollection<Tuple<string, ObservableCollection<Book>>>(
            booksGroup.Select(x => Tuple.Create(x.Key,
                                            new ObservableCollection<Book>(x))));

You simply do not have an observable collection bound to your grid.

in this line

var teamGroups = booksList.BooksDetail.GroupBy(team => team.BookCategory)
                                       .OrderBy(team => team.Key.ToString());

you create a linq statement that wraps your observable collection and exposes IOrderedEnumerable which you bind to your view. And this interface obviously does not forward change events from your collection and your property.

To solve this you need to hold in your BooksDetails (or any other property in your view model) ObservableCollection that is already sorted and grouped and bind it directly in xaml. Setting source in this maner:

this.groupedItemsViewSource.Source = booksList.BooksDetail;

will not allow grid to recreate it self when BooksDetail property is changed.


var observableCollection = new ObservableCollection<Tuple<Key, ObservableCollection<Book>>>(
          teamGroups.Select(x=>Tuple.Create(x.Key, 
                                            new ObservableCollection<Book>(x))));

If you want to crate second property note that you will have to synchronize them when books are added, deleted or have category changed.

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