【问题标题】:Wp7, C# Navigate when download is completed in viewModelWp7,C#在viewModel中完成下载时导航
【发布时间】:2012-02-14 13:56:10
【问题描述】:

所以,我正在为 wp7 制作一个应用程序。 为简单起见,这些是我的文件:

  • Lo​​ginPage.xaml(启动页面)
  • MainPage.xaml
  • MainViewModel.cs
  • ItemViewModel.cs

在 MainViewModel.cs 中,我包含了以下函数:

private void DownloadItems()
    {
        string key = this.User.Key;
        WebClient wc = new WebClient();
        wc.DownloadStringCompleted += callback;
        wc.DownloadStringAsync(new Uri("http://localhost/items?key=" + key)); //JSON
    }

以及回调函数:

private void callback(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            List<ItemViewModel> col = Deserialize_ItemViewModel(e.Result); // deserialize JSON to List<ItemViewModel>
            this.Items = new ObservableCollection<ItemViewModel>(col);
            ItemDB.Sponsors.InsertAllOnSubmit(col);
            ItemDB.SubmitChanges();
            this.IsDataLoaded = true;
            // ???
        }
    }

当用户登录时,登录将被处理,当一切正常时,将使用新设置的 User.Key 调用 DownloadItems。

我需要在下载过程中显示 ProgressIndicator,当下载完成并处理完毕后,我想导航到 MainPage.xaml,届时它将准备就绪。

希望有人能帮助我,在此先感谢!

【问题讨论】:

    标签: c# silverlight windows-phone-7 mvvm viewmodel


    【解决方案1】:

    我想我会尝试以不同的方式解决它。让你的 LoginPage 只处理登录,然后你重定向到你的主页。

    在您的视图模型中,为主页创建一个名为 Loading 之类的 bool 属性,您可以在异步调用期间将其设置为 true。将此绑定到进度条的可见属性,以便当Loading 为真时显示,使用转换器处理布尔-> 可见。加载数据后,您只需将Loading 设置为 false,这将导致进度条消失。同时,您还将控件/视图的可见属性绑定到Loading,但这将使用不同的转换器,即进度条转换器的反转值。

    希望这会有所帮助。

    更新:我错过了你已经有一个IsDataLoaded,这是在你的视图模型上吗?转换器应如下所示:

    public class VisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, 
                   CultureInfo culture)
        {
            if (value != null && value is bool && parameter != null)
            {
                var bValue = (bool) value;
                var visibility = (Visibility)Enum.Parse(
                typeof (Visibility), parameter.ToString(),true);
                if (bValue) return visibility;
                return visibility == 
                Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
            }
    
            return null;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter,
                       CultureInfo culture)
        {
             throw new NotImplementedException();
        }
    }
    

    然后像这样使用它:

    Visibility="{Binding IsDownloading, Converter={StaticResource VisibilityConverter}, ConverterParameter=Visible}"
    

    示例代码来自:http://dotnetbyexample.blogspot.com/2010/11/converter-for-showinghiding-silverlight.html

    【讨论】:

    • 我认为这将适用于我的应用程序,但你知道我是否可以从我的视图模型或此变量更新时调用非静态函数(导航函数)吗?
    • 查看 Pavan 的另一个答案,了解如何从后台线程调用 UI 线程。但是如果您使用我为您提供的解决方案,我认为您不需要它。
    • @Qurben,您不应该在视图模型中这样做,即调用导航功能。 viewmodel 与导航无关,它是视图的模型。视图模型应该只标记,通知属性已更改,周围环境发生了变化,然后由周围环境来处理该变化。最好的流程可能是:导航到页面并显示临时视图,直到加载数据。加载数据时显示预期的视图。
    • 好吧,有了导航功能,我的意思是告诉登录页面下载完成,可以进入下一页了。我可以设置某种守护函数,当某个变量变为真时该函数将继续执行?不挂 te ui 线程?
    • 但这就是我的意思,让登录页面处理登录,让下一页处理数据相关的东西。如果您使用后退按钮导航回您的应用程序,这也会变得更好。
    【解决方案2】:

    当您以任何异步方式更新 UI 时,您可以按以下方式使用 Dispatcher

    Dispatcher.BeginInvoke(delegate
    
    {
    
     NavigationService.Navigate(new Uri("/Folder/pagename.xaml", UriKind.Relative));
    
    });
    

    我认为它对你有帮助。

    【讨论】:

    • 我知道我可以从页面本身的回调函数中做到这一点,但我不能从我的视图模型中使用调度程序。我想我会把所有异步的东西都移到页面上,因为这样更容易。
    猜你喜欢
    • 1970-01-01
    • 2013-12-22
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多