【问题标题】:Pivot Itemssource not updatingPivot Itemssource 未更新
【发布时间】:2013-04-17 20:47:54
【问题描述】:

嗨,我有一个 Category 类,我正在从 API 下载数据并显示在 Pivot 中,现在对于 Pivot 的索引 0 数据加载,当用户切换到其他 PivotItems 时,我添加了一个 Pivot selection changed event并加载数据。但问题是ItemsSource 没有更新。如果我喜欢这个pivot.itemssource="";和pivot.itemssource=mylist;我还必须将pivot.selectedIndex 更改为当前索引,在这种情况下翻转不平滑,由于pivot.itemssource="",它首先变为0 索引;然后来到实际的地方。请帮我解决这个问题,以便它自动绑定和更新。我的课程如下:

类别.xaml

<Grid x:Name="LayoutRoot" >

        <controls:Pivot Margin="0,53,0,28" x:Name="CategoryList" Foreground="White" SelectionChanged="Pivot_SelectionChanged" ItemsSource="{Binding Constants.categoryDetails}" >
            <controls:Pivot.HeaderTemplate>
                <DataTemplate>
                    <TextBlock x:Name="PivotTitle" Text="{Binding name}"></TextBlock>
                </DataTemplate>
            </controls:Pivot.HeaderTemplate>
            <!--Panorama item one-->
            <controls:Pivot.ItemTemplate>
                <DataTemplate>
                    <Grid>
                       <ListBox x:Name="subCatList" ItemsSource="{Binding subcategories}" ScrollViewer.VerticalScrollBarVisibility="Visible">
                            <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <Border BorderThickness="2" BorderBrush="White">
                                            <Grid Width="420" Height="70" Background="#85000000">
                                                <TextBlock Text="{Binding name}"  FontFamily="Verdana" FontSize="35" Margin="10,10,64,5" TextWrapping="Wrap" ></TextBlock>
                                            </Grid>
                                        </Border>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                       </ListBox>
                     </Grid>
                </DataTemplate>
            </controls:Pivot.ItemTemplate>
        </controls:Pivot>


    </Grid>



    <!--Panorama-based applications should not show an ApplicationBar-->

</phone:PhoneApplicationPage>

分类.cs

namespace MyApp.Views
{
    public partial class Category : PhoneApplicationPage
    {
                     List<WebClient> webclientsList = new List<WebClient>();
                     private int selectedIndex=0;
                    private ListBox subCatList;
                    public readonly DependencyProperty ListVerticalOffsetProperty;
                    public Category()
        {
            InitializeComponent();
            for (int i = 0; i < Constants.catList.Length; i++)
            {
                       WebClient wb = new WebClient();
                       CategoriesClass ct = new CategoriesClass();
                       ct.name = Constants.catList[i];
                       webclientsList.Add(wb);
                       Constants.categoryDetails.Add(ct);
            }
                  loadCategory();

        }

        private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            selectedIndex = CategoryList.SelectedIndex;
            if (Constants.categoryDetails[selectedIndex].subcategories==null) {
                loadCategory();

            }
            else{

            }
        }

        private void loadCategory()
        {

            try
            {

                String Url = Constants.BASE_URL + "/get-category-data/?client_key=" + Constants.CLIENT_KEY;

                webclientsList[selectedIndex].DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClientCategoryDownload);
                webclientsList[selectedIndex].DownloadStringAsync(new Uri(Url));

            }
            catch (Exception e)
            {
                Console.WriteLine("Error Occured"+e.StackTrace);
            }
        }

        void webClientCategoryDownload(object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                if (e.Error != null)
                {
                    Console.WriteLine("Error geting category");
                    return;

                }

                CategoryClass ctClass = new CategoryClass();
                ctClass = JsonConvert.DeserializeObject<CategoryClass>(e.Result);



                if (ctClass.name!=null)
                {
                    Console.WriteLine("Category Loaded");
                    Constants.categoryDetails[selectedIndex].categoryDetails = ctClass;
                    Constants.categoryDetails[selectedIndex].subcategories = new ObservableCollection<SubCategories>();
                    foreach (var its in ctClass.categories)
                    {
                        foreach(var chi in its.children){

                            Constants.categoryDetails[selectedIndex].subcategories.Add(chi);
                        }

                    }


                    CategoryList.ItemsSource = "";
                    CategoryList.SelectedIndex = selectedIndex;
                    CategoryList.ItemsSource = Constants.categoryDetails;

                    for(int i=0;i<Constants.categoryDetails.Count;i++){

                        foreach (var x2 in Constants.categoryDetails[selectedIndex].subcategories)
                        {
                            Console.WriteLine("SubCategory is :"+x2.name);
                        }
                    }

                }
                else {

                    Console.WriteLine("Categories Doesnt Exists ");
                }

            }
            catch (Exception e1)
            {
                Console.WriteLine("Exception Occured:"+e1.StackTrace);
            }
        }

        private void Facebook_login(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Views/Login.xaml", UriKind.Relative));
        }

     }
}

【问题讨论】:

    标签: windows-phone-7 mvvm wpf-controls wpftoolkit


    【解决方案1】:

    首先尝试设置

     pivot.itemssource=null;
    

    然后

     pivot.itemssource=myList;
    

    但这是错误的方式。

    如果你想成为一名优秀的Windows Phone开发者,你必须知道MVVM是什么。

    首先,你必须阅读并理解this article

    然后尝试了解如何使用现有的 mvvm 工具包,例如MVVM LightCaliburn.Micro

    您应该很好地了解如何使用 MVVM,然后您才能自己解决问题。

    希望对您有所帮助。

    同时检查this useful question

    还有thisthisthisthis

    【讨论】:

    • 我已经阅读了关于 MVVM 的文章,我能够理解 MVVM 的功能,现在当我更新它没有更新的集合时,Inotify 属性没有更新,请帮助。
    • 无论如何,我自己找到了解决方案...感谢@jimpanzer 的帮助
    • @Artist404 您应该添加自己的解决方案作为答案并将其标记为已接受的解决方案。请参阅FAQHelp Center > Answering
    【解决方案2】:

    以下是我在项目中使用 MVVM 所遵循的步骤。

    Install MVVM from silverlight
    http://www.galasoft.ch/mvvm/installing/  Dont know the exact link but I think its available here.
    
    Now restart your visual studio.
    
    Go to Right click on your project and add new Items to your project.
    Now add Model View Locator inside ViewModel  folder. (It will be good practice to keep these file 
    
    into a new folder like ViewModel, View, Model)
    
    Now you have created a viewlocator which handles all the process like cleaning for a viewmodel.
    
    Now in the same folder create a modelview for your requirement edit like below, and also you are 
    
    free to add more parameters acc to your requirement.
    
    using GalaSoft.MvvmLight;
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using MyProject.Model;
    namespace MyProject.ViewModel
    {
    
        public class ProductViewModel : INotifyPropertyChanged
        {
             private ObservableCollection<ProductsClass> productData;
    
             public ObservableCollection<ProductsClass> ProductData
            {
                get
                {
                    return productData;
                }
    
                set {
                    productData = value;
                    RaisePropertyChanged("ProductData");
                }
            }
    
    
             public ProductViewModel(ObservableCollection<ProductsClass> productData)
            {
                ProductData = productData;
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void RaisePropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
    
            if (handler != null)
    
                 {
    
                     handler(this, new PropertyChangedEventArgs(propertyName));
    
                 }
    
    
        }
    
    
    
    
    
            /// <summary>
            /// Initializes a new instance of the ProductViewModel class.
            /// </summary>
            public ProductViewModel()
            {
                ////if (IsInDesignMode)
                ////{
                ////    // Code runs in Blend --> create design time data.
                ////}
                ////else
                ////{
                ////    // Code runs "for real": Connect to service, etc...
                ////}
            }
    
            ////public override void Cleanup()
            ////{
            ////    // Clean own resources if needed
    
            ////    base.Cleanup();
            ////}
        }
    }
    
    
    
    Now we have created our modelview, we have to mention something for this in our locator as 
    
    follows(Make the necessary changes only):
    
    
    
    
    
    
    
    
    namespace Myproject.ViewModel
    {
    
        public class ViewModelLocator
        {
    
    
    
    
    
        private static MainViewModel _main;
    
    
    
            /// <summary>
            /// Initializes a new instance of the ViewModelLocator class.
            /// </summary>
            private static ProductViewModel _viewModelProduct;
    
    
    
            public ViewModelLocator()
            {
    
    
                CreateMain();
    
                CreateViewModelProduct();
    
    
            }
    
    
    
            /// <summary>
            /// Gets the Main property.
            /// </summary>
            public static MainViewModel MainStatic
            {
                get
                {
                    if (_main == null)
                    {
                        CreateMain();
                    }
    
                    return _main;
                }
            }
    
            /// <summary>
            /// Gets the Main property.
            /// </summary>
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
                "CA1822:MarkMembersAsStatic",
                Justification = "This non-static member is needed for data binding purposes.")]
            public MainViewModel Main
            {
                get
                {
                    return MainStatic;
                }
            }
    
            /// <summary>
            /// Provides a deterministic way to delete the Main property.
            /// </summary>
            public static void ClearMain()
            {
                _main.Cleanup();
                _main = null;
            }
    
            /// <summary>
            /// Provides a deterministic way to create the Main property.
            /// </summary>
            public static void CreateMain()
            {
                if (_main == null)
                {
                    _main = new MainViewModel();
                }
            }
    
            /// <summary>
            /// Cleans up all the resources.
            /// </summary>
            public static void Cleanup()
            {
                ClearMain();
    
                ClearViewModelProduct();
    
            }
    
    
    
            //Product model declaration
    
            /// <summary>
            /// Gets the ViewModelPropertyName property.
            /// </summary>
            public static ProductViewModel ProductViewModelStatic
            {
                get
                {
                    if (_viewModelProduct == null)
                    {
                        CreateViewModelProduct();
                    }
    
                    return _viewModelProduct;
                }
            }
    
            /// <summary>
            /// Gets the ViewModelPropertyName property.
            /// </summary>
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
                "CA1822:MarkMembersAsStatic",
                Justification = "This non-static member is needed for data binding purposes.")]
            public ProductViewModel ViewModelProduct
            {
                get
                {
                    return ProductViewModelStatic;
                }
            }
    
    
    
            /// <summary>
            /// Provides a deterministic way to create the ViewModelPropertyName property.
            /// </summary>
            public static void CreateViewModelProduct()
            {
                if (_viewModelProduct == null)
                {
                    _viewModelProduct = new ProductViewModel();
                }
            }
    
            /// <summary>
            /// Provides a deterministic way to delete the ViewModelPropertyName property.
            /// </summary>
            public static void ClearViewModelProduct()
            {
                //_main.Cleanup();
                _viewModelProduct = null;
            }
    
    
        }
    }
    
    
    Now inside your VIew create a variable like 
    
     private ProductViewModel pvm;
    
    inside constructor add this:
    
     pvm = (ProductViewModel)Resources["pviewModel"];
    
    Add this in your loaded method:
    
      Binding binding = new Binding("ProductData") { Source = pvm };
    
    
    Like
    
    
    
     private void Product_Loaded(object sender, RoutedEventArgs e)
            {
                //Additional Code
                pvm.ProductData = Constants.productDet;
                //Additional Code          
    
                Binding binding = new Binding("ProductData") { Source = pvm };
            }
    
    
    Now after adding some more code in your xaml file whenever you update anything in .cs it will 
    
    automatically reflect in your view.
    
    
    Make following in your xaml file:
    
    DataContext="{Binding ViewModelProduct, Source={StaticResource Locator}}"
        Loaded="Product_Loaded"> at the top declaration
    
    
    
        <phone:PhoneApplicationPage.Resources>
    
            <viewModel:ProductViewModel x:Key="pviewModel" />
    
        </phone:PhoneApplicationPage.Resources>
    
    
    
    Now the productsclass will be similar like this(its on u how u add parameters acc to ur requirement)
    
    
    
    
    
    namespace Myproject.Model
    {
        public class ProductsClass : INotifyPropertyChanged
        {
            private string name;
            public string Name
            {
                get { return name; }
                set
                {
                    if (name != value)
                    {
                        name = value;
                        // NotifyPropertyChanged("Name");
                    }
                }
            }
    
    
            private ProductClass productDetailsOverview;
            public ProductClass ProductDetailsOverview
            {
                get { return productDetailsOverview; }
                set
                {
                    if (productDetailsOverview != value)
                    {
                        productDetailsOverview = value;
                        NotifyPropertyChanged("ProductDetailsOverview");
                    }
                }
            }
    
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(String propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (null != handler)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
        }
    
    
        public class ProductClass 
        {
    
            public long product_start_offset { get; set; }
            public ObservableCollection<FiltersData> filters_data { get; set; }
            public long product_end_offset { get; set; }
            public long product_count { get; set; }
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(String propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (null != handler)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    
    
    and you can use ProductDetailsOverview in the itemssource to access any parameter like
    
    ItemsSource="{Binding ProductDetailsOverview.product_list}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 2019-03-18
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      相关资源
      最近更新 更多