2

我正在尝试在 WP7 项目中使用性能进度条,但我在异步 webclient 调用时遇到了问题。我的代码如下:

更新

    public MainPage()
    {
        InitializeComponent();
         ...................

        this.Loaded += new RoutedEventHandler(MainPage_Loaded);}

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (!App.ViewModel.IsDataLoaded)
        {
            App.ViewModel.LoadData();
        }
    }

以及我实现 LoadData 函数的 ViewModel

    private bool _showProgressBar = false;
    public bool ShowProgressBar
    {
        get { return _showProgressBar; }
        set
        {
            if (_showProgressBar != value)
            {
                _showProgressBar = value;
                NotifyPropertyChanged("ShowProgressBar");
            }
        }
    public void LoadData()
    {
        try
        {
            string defaulturl = "http://....";
            WebClient client = new WebClient();
            Uri uri = new Uri(defaulturl);
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            ShowProgressBar = true;
            client.DownloadStringAsync(uri);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

        this.IsDataLoaded = true;

    }

    void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        try
        {
            //fetch the data
           ShowProgressBar = false;
        }

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {.....
    } 

主页 Xaml

    <toolkit:PerformanceProgressBar Margin="0,-12,0,0" x:Name="performanceProgressBar" IsIndeterminate="true" Visibility="{Binding ShowProgressBar, Converter={StaticResource BooleanToVisibilityConverter}}"/>

我的问题是因为 WebClient 在执行时是一个异步方法,所以 LoadData 已经执行了,我不知道在哪里放置 performanceProgressBar.Visibility

任何帮助,将不胜感激。谢谢!

4

2 回答 2

1

在您在评论中解释得更多之后,我明白了更多。听起来您想将布尔属性绑定到进度条的可见性。你需要一个布尔到可见性的转换器(谷歌一下,很容易找到)。

然后你可以做这样的事情:

private bool _showProgressBar = false;
public bool ShowProgressBar
{
    get { _return _showProgressBar; }
    set 
    { 
        _return _showProgressBar;
        OnPropertyChanged("ShowProgressBar");
    }
}

public void LoadData()
{
    try
    {
        string defaulturl = "http://....";
        WebClient client = new WebClient();
        Uri uri = new Uri(defaulturl);
        client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

        ShowProgressBar = true;

        client.DownloadStringAsync(uri);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

    this.IsDataLoaded = true;

}

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    try
    {
        //fetch the data
        ShowProgressBar = false;
    }

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

}

在视图上:

<MyProgressBar Visibility={Binding Path=ShowProgressBar, Converter={StaticResource MyBoolToVisibleConverter}>

显然,MSFT 已经为您提供了一个转换器......这对我来说是个新闻:http: //msdn.microsoft.com/en-us/library/system.windows.controls.booleantovisibilityconverter.aspx

于 2012-06-15T21:03:40.947 回答
0

你只需要回到 UI 线程——它Dispatcher可以帮助你,我使用的一个常见片段(在我的 ViewModelBase 中是:

    protected delegate void OnUIThreadDelegate();
    /// <summary>
    /// Allows the specified deelgate to be performed on the UI thread.
    /// </summary>
    /// <param name="onUIThreadDelegate">The delegate to be executed on the UI thread.</param>
    protected void OnUIThread(OnUIThreadDelegate onUIThreadDelegate)
    {
        if (Deployment.Current.Dispatcher.CheckAccess())
        {
            onUIThreadDelegate();
        }
        else
        {
            Deployment.Current.Dispatcher.BeginInvoke(onUIThreadDelegate);
        }
    }

这可以简单地用于:

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    try
    {
        //fetch the data

        this.OnUIThread(() =>
        {
            performanceProgressBar.Visibility = Visibility.Collapsed; // This code will be performed on the UI thread -- in your case, you can update your progress bar etc.
        });

    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

} 
于 2012-06-15T20:49:47.017 回答