每次导航到Page时重新加载数据

时间:2014-12-19 15:59:33

标签: c# xaml windows-phone-8

我有这个Windows Phone页面,我通过标准的ViewModel范围加载数据。

public Profile()
        {
            InitializeComponent();
            App.PersonalizedViewModel.favorites.Clear();
            DataContext = App.PersonalizedViewModel;
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {

            if (!App.PersonalizedViewModel.IsDataLoaded)
            {
                App.PersonalizedViewModel.LoadData();

            }
}

这很好用。但是,当我从其他页面导航到此页面时,数据仍然相同。我的意思是LoadData()方法应该重新检查更新的数据吗?请建议。

编辑:

我的PersonalizedViewModelClass:

public class PersonalizationViewModel: INotifyPropertyChanged
{
    public PersonalizationViewModel()
    {
        this.favorites = new ObservableCollection<ItemViewModel>();
        this.Bar = new ObservableCollection<Bars>();
    }

    public ObservableCollection<ItemViewModel> favorites { get; private set; }
    public ObservableCollection<Bars> Bar { get; private set; }

    private string _sampleProperty = "Sample Runtime Property Value";

    public string SampleProperty
    {
        get
        {
            return _sampleProperty;
        }
        set
        {
            if (value != _sampleProperty)
            {
                _sampleProperty = value;
                NotifyPropertyChanged("SampleProperty");
            }
        }
    }

    public bool IsDataLoaded
    {
        get;
        private set;
    }

    /// <summary>
    /// Creates and adds a few ItemViewModel objects into the Items collection.
    /// </summary>
    public async void LoadData()
    {
        favorites.Clear();
        try
        {
            var query = ParseObject.GetQuery("Favorite")
                .WhereEqualTo("user", ParseUser.CurrentUser.Username);
            IEnumerable<ParseObject> results = await query.FindAsync();

            this.favorites.Clear();

            foreach (ParseObject result in results)
            {
                string venue = result.Get<string>("venue");
                string address = result.Get<string>("address");
                string likes = result.Get<string>("likes");
                string price = result.Get<string>("price");
                string contact = result.Get<string>("contact");
                this.favorites.Add(new ItemViewModel { LineOne=venue, LineTwo=address, LineThree=likes, Rating="", Hours="", Contact=contact, Price=price, Latitude="", Longitude="" });

            }




            if (favorites.Count == 0)
            {
                //   emailPanorama.DefaultItem = emailPanorama.Items[1];
                MessageBox.Show("You do not have any saved cafes. Long press a cafe in main menu to save it.");

            }
        }
        catch (Exception exc)
        {
            MessageBox.Show("Data could not be fetched!", "Error", MessageBoxButton.OK);

        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

PersonalizedViewModel的实现:

protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        await App.PersonalizedViewModel.LoadData();

        user_tb.Text = ParseUser.CurrentUser.Username;


        if (NavigationContext.QueryString.ContainsKey("item"))
        {
            var index = NavigationContext.QueryString["item"];
            var indexParsed = int.Parse(index);
            mypivot.SelectedIndex = indexParsed;
        }

        if (NavigationService.BackStack.Any())
        {
            var length = NavigationService.BackStack.Count() - 1;
            var i = 0;
            while (i < length)
            {
                NavigationService.RemoveBackEntry();
                i++;
            }
        }
    }

5 个答案:

答案 0 :(得分:2)

我没有看到问题,但是,我认为你需要缩小问题范围。

首先,您从2个位置调用LoadData。 1来自MainPage_Load,1来自OnNavigatedTo。在MainPage_Load中它是有条件的并且在OnNavigatedTo它总是被调用。我建议您通过代码而不是2来获得单一路径,这样您就无法获得不同的体验。我个人建议(不知道所有细节)你从OnNavigatedTo而不是MainPage_Load调用加载数据。如果你想有条件地做到这一点很好但是如果你从内存加载数据,它实际上是不必要的,因为你不会提高性能超过几毫秒。此外,如果您没有从内存加载,您可能不希望有条件地加载它,因为基础数据可能已更改。在任何一种情况下,加载数据的选择都应该移出视图并进入数据层(但这是另一个帖子)。

一旦选择了单个路径(即从MainPage_Load或OnNavigatedTo调用LoadData),您应该使用调试器。在LoadData方法中设置一个断点,如果正确调用它,那么您的问题比您发布的问题更具体。以下是一些需要考虑的问题(您可能希望从最后一个问题开始,然后向后工作)

问题:

  1. 是否正确调用LoadData?
  2. ParseObject是否有正确的数据?
  3. ParseUser ... UserName是否设置正确?
  4. foreach被执行了正确的次数(即你的查询结果是否有正确的项目数量?)
  5. 情侣代码提示与此问题完全无关:

    1. 通过代码的单一路径。不要从多个地方调用LoadData。
    2. 不要在同一方法中两次调用favorites.clear()。 (在LoadData中调用两次)
    3. 一致的命名。收藏夹是小写但Bar是大写。
    4. 用户正确的数据类型。在ItemViewModel上,您有小时,纬度和经度。你把它们作为字符串。这些显然不是字符串。此外,您不应将它们设置为空。空意味着它们已设置为值。 Emtpy是一个有效值。 Null表示未设置。为了保持对象的清洁和准确,您需要准确了解如何设置事物,然后适当地处理影响。如果你真的希望它们被初始化为空字符串,那么至少在ItemViewModel的构造函数中执行它,这样每个调用者都不必知道如何初始化每个属性。如果你继续使用这种做法,我保证会导致错误的代码。
    5. 请将评论视为建设性批评而不是批评。我知道很多人不喜欢听这些东西,但我领导的团队会在他们开始遵循这些指导方针之前写错误。

      祝你好运,

      汤姆

答案 1 :(得分:0)

而不是定义这个

App.PersonalizedViewModel.favorites.Clear();
DataContext = App.PersonalizedViewModel;
this.Loaded += new RoutedEventHandler(MainPage_Loaded);

进入constructor,即Profile我建议您从Constructor删除此代码并将其添加到OnNavigatedTo。所以数据将在navigation

之后加载

您的OnNavigatedTo方法如下所示

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    App.PersonalizedViewModel.favorites.Clear();
    DataContext = App.PersonalizedViewModel;
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);

}

你的问题可能会解决。

修改

尝试此查询

 var results = (from find in ParseObject.GetQuery("Favorite").WhereEqualTo("user", ParseUser.CurrentUser.Username) select find);

试过这个:

var query = from favorite in ParseObject.GetQuery("Favorite")
                            where favorite.Get<string>("user") == ParseUser.CurrentUser.Username
                            select favorite;
                IEnumerable<ParseObject> results = await query.FindAsync();

答案 2 :(得分:0)

我有一个类似的问题。你想在这里做的是生成一个新的Page实例。我可以用两种方式做到这一点。 单向方法是强制GUID以及页面导航URI,它将创建页面的新实例,并且您的加载数据()将起作用。

      NavigationService.Navigate(new Uri(String.Format("/MainPage.xaml?item={0}", Guid.NewGuid().ToString()), UriKind.RelativeOrAbsolute));

在用户控件中实现页面的这一部分的第二种方法。像为Load Data()创建一个用户控件并将其放在构造函数中。每次加载页面时都会生成一个新的实例。

答案 3 :(得分:0)

如果前端问题仍然存在,您可以试试这个。

1.您在xaml页面中提到了以下属性吗?

 <UserControl Loaded="MainPage_Loaded">

因此,每次页面加载数据时都会加载到页面上。

2.数据必须存在,如果您在后面的代码中没有问题,因为它是WPF应用程序而不是网页。

希望你觉得它很有用。

答案 4 :(得分:0)

需要进行两项更改..

从OnNavigatedTo中删除this.Loaded。这可能不是必需的。

第二步将LoadData移动到OnNavigatedTo方法

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
   base.OnNavigatedTo(e);

   App.PersonalizedViewModel.favorites.Clear();
   DataContext = App.PersonalizedViewModel;
   // this.Loaded += new RoutedEventHandler(MainPage_Loaded);

   if (!App.PersonalizedViewModel.IsDataLoaded)
   {
       App.PersonalizedViewModel.LoadData();
   }
}

出于调试目的,您可以删除行if (!App.PersonalizedViewModel.IsDataLoaded)并尝试。