【问题标题】:Telerik BusyIndicator does not DisplayTelerik BusyIndi​​cator 不显示
【发布时间】:2013-03-19 10:39:23
【问题描述】:

我正在使用 WCF 服务

我有这个问题:

当我在异步函数调用开始时从服务器为我的 GridView 检索数据时,我设置了 IsBusy = "True" 。方法调用后,我设置了IsBusy = "False"。在方法调用期间RadBusyIndicator 不显示。我无法理解问题所在。

我已经上传了一个有这个问题的简单项目。你能检查一下吗? Download

【问题讨论】:

    标签: c# .net wpf wcf silverlight


    【解决方案1】:

    我在 BackgroundWorker 中移动了加载,你可以试试这个:

    private void LoadData()
    {
        //Activate BudyIndicator
        App.Instance.SetBusy();
    
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += (o, ea) =>
        {
            ObservableCollection<CustomerModel> LoadedCustomers = null;
    
            //Create Client
            proxy.ServicesClient client = new proxy.ServicesClient();
            ObservableCollection<Customer> customers = client.GetCustomers();
    
            LoadedCustomers = new ObservableCollection<CustomerModel>();
            foreach (var item in customers)
            {
                LoadedCustomers.Add(new CustomerModel()
                {
                    CustomerId = item.CustomerId,
                    Title = item.Title,
                    FirstName = item.FirstName,
                    MiddleName = item.MiddleName,
                    LastName = item.LastName,
                    CompanyName = item.CompanyName,
                    SalesPerson = item.SalesPerson,
                    EmailAddress = item.EmailAddress,
                    Phone = item.Phone
                });
            }
            client.Close();
    
            //Define return value
            ea.Result = LoadedCustomers;
        };
        worker.RunWorkerCompleted += (o, ea) =>
        {
            //Get returned value
            ObservableCollection<CustomerModel> model = ea.Result as ObservableCollection<CustomerModel>;
            if (model != null)
            {
                Customers = model;
            }
    
            //Desactivate BusyIndicator
            App.Instance.UnSetBusy();
        };
        worker.RunWorkerAsync();
    }
    

    【讨论】:

    • 我按照你写的那样做了,但没有用。起初它进入 worker.RunWorkerCompleted {} 并且 ea.Result 为空,然后分配到 worker.DoWork {};这个 BackgroundWorker 类是什么?线程???
    • BackgroundWorker 允许异步进程。通过在 DoWork 中填充其“ea.Result”属性,您可以在“RunWorkerCompleted”中的调用线程中检索它。
    • 但正如我告诉你的,它首先进入worker.RunWorkerCompleted,此时ea.Result为空,只有在worker.DoWork完成之后
    • 这才是真正的BackgroundWorker本身启动一个异步进程(GetCustomersAsync)。在 BackgroundWorker 中调用 GetCustomers(),您可以使用 BusyIndi​​cator 上传数据。我希望这能解决您的问题。
    • 首先:我们不是 GetCustomers,而是 GetCustomersAsync。第二:它没有返回类型,它是无效的。您可以下载我的项目,进行更正并将其发回给我吗?
    【解决方案2】:

    好的,我明白你的问题了。代理上的 Close 方法等待异步调用的结果。 只需移动您的 client.Close();在 GetCustomersCompleted 方法中,这将起作用。 (用您的样品测试)

    private proxy.ServicesClient client = null;
    private void LoadData()
    {
        App.Instance.SetBusy();
    
        client = new proxy.ServicesClient();
        client.GetCustomersCompleted += (s, e) =>
        {
            if (e.Error != null)
            {
                throw new Exception();
            }
            else
            {
                Customers = new ObservableCollection<CustomerModel>();
    
                foreach (var item in e.Result)
                {
                    Customers.Add(new CustomerModel()
                        {
                            CustomerId = item.CustomerId,
                            Title = item.Title,
                            FirstName = item.FirstName,
                            MiddleName = item.MiddleName,
                            LastName = item.LastName,
                            CompanyName = item.CompanyName,
                            SalesPerson = item.SalesPerson,
                            EmailAddress = item.EmailAddress,
                            Phone = item.Phone
                        });
                }
    
                OnPropertyChanged("Customers");
            }
            client.Close();//Close after the return
            App.Instance.UnSetBusy();
        };
        client.GetCustomersAsync();
        //client.Close();
    }
    }
    

    【讨论】:

    • 又不行了:(,你能写在我上传的这个项目里吗??发给我
    • 我不必发送项目存储库。但可能是负载太快了..为了测试我更改了“Services.cs”添加暂停5s为:public ObservableCollection &lt;Customer&gt; GetCustomers () { Thread.Sleep (5000); return new CustomerBLL (). GetCustomers (); }
    【解决方案3】:

    如果您的窗口 xaml 不在繁忙指示器内,则它可能不会显示。使用该控件,您需要将繁忙指示器设置为 true 时希望被屏蔽的内容放入指示器标记​​内。如果您的 UserControl 的主要显示项是 Grid,则将网格包装在忙碌指示符标签中。

    <UserControl>
      <telerik:RadBusyIndicator IsBusy={Binding Busy}>
          <Grid>
             content...
          </Grid>
       </telerik:RadBusyIndicator>
    </UserControl>
    

    这应该会给你你正在寻找的结果。

    【讨论】:

    • 我做到了,但不能再次工作。好吧,我做了实验,在 GetCustomersCompleted 事件中删除我设置 IsBusy = "false" 的行,并注意数据何时加载,然后显示 BusyIndi​​cator。
    【解决方案4】:

    如果您在控制器上使用 IsBusy 属性的绑定,我假设您是,那么您必须实现 INotifyPropertyChanged 接口,以便在更改绑定属性的值时通知 UI 该更改并更新本身。 您的视图模型应该有一个带有 setter 的属性,如下所示:

        public bool Busy
        {
            get{return _Busy;}
            set
            {
               if(value != _Busy)
                 _Busy = value;
               OnPropertyChanged("Busy");
            }
    
        }
    

    这将通知 UI 更改; 如果您已经这样做了,那么我将需要查看更多相关代码以提供更多帮助。

    在我再次查看您的上一篇文章之后,如果您将 IsBusy 属性设置为字符串值,这是您的问题,因为该属性采用布尔值。

    【讨论】:

    【解决方案5】:

    根据您的代码,我假设您只希望将繁忙指示器放在主窗口的内容控件上。我的建议是为主窗口创建一个视图模型并将其用作页面的数据上下文。如上所述,我还将在视图模型上设置一个属性,并设置到该属性的绑定。在视图模型中,您可以对数据存储进行异步调用,并在返回时填充集合属性(推荐 ObservableCollection)并将您的 ListBox 的 IitemsSource 属性绑定到该属性。 我希望这会有所帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 2011-06-25
      • 2012-11-11
      • 2012-07-10
      • 2013-04-19
      • 2011-04-02
      • 2013-05-19
      • 2012-09-05
      相关资源
      最近更新 更多