WPF扩展工具箱:将BusyIndicator绑定到属性

3

我有一个BusyIndicator,我将IsBusy绑定到我的视图模型中的Busy属性。

<xctk:BusyIndicator IsBusy="{Binding Busy}" x:Name="busyBox" Grid.Row="2"
              HorizontalAlignment="Center"
            VerticalAlignment="Center" BusyContent="Contacting Server" >
    </xctk:BusyIndicator>

我在启动一个Web服务调用(异步)时将busy设置为true,并在回调函数中将其设置为false。
第一次这样做非常好,但之后每次都不再显示忙指示器。我在回调函数中添加了一个thread.sleep(只是为了防止第二次移动得太快)。
我知道我的属性通知正确,因为其他绑定的控件按预期工作。只是似乎忙指示器仅适用于一次使用
(顺便说一句,我正在使用MVVM Light Toolkit v3)
视图模型代码
this.Busy = true; //This proverty is declared correctly with notifications etc
IPersonSearchService searcher = new PersonSearchService(); //class that does my      webservice, ad i pass it a callback method from my UI (see below)
searcher.FindByPersonDetails(ps, GetAllPeopleCallback);


private void GetAllPeopleCallback (PersonSearchResult result, Exception e)
    {
        this.Busy = false;
        ((Models.PersonSearch)this.Model).Persons = result.Persons; //bound to my grid
         CommandManager.InvalidateRequerySuggested();  //i need to do this to make a button who's canexecute command binding happen         
    }

这是调用网络服务的类。
class PersonSearchService : IPersonSearchService
{
    public void FindByPersonDetails(WSPersonSearch.PersonSearch ps, Action<PersonSearchResult, Exception> Callback)
    {
        BackgroundWorker worker = new BackgroundWorker();

        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            WSPersonSearch.PersonSearch search = (WSPersonSearch.PersonSearch)args.Argument;
            PersonSearchWebServiceClient wc = new PersonSearchWebServiceClient();
            PersonSearchResult r = wc.FindByPersonDetails(ps);
            args.Result = r;
        };

        worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
        {
            PersonSearchResult result = (PersonSearchResult)args.Result;
            Callback(result, null);
        };

        worker.RunWorkerAsync();
    }
}

UI上的其他所有内容都表现良好。我的按钮能够正确激活/停用。我的网格得到了良好的更新等等。


你能发布回调的ViewModel的代码吗? - Rohit Vats
如果BusyIndicator控件是问题所在,您可以随时创建自己的控件。这并不像看起来那么困难(您只需要将忙指示器和视图内容放入一个没有行的网格中,并将指示器的可见性绑定到您的繁忙属性)。 - Daniel Castro
我认为问题不在于BusyIndicator,可能是异步线程的问题。可能与WPF的可视化线程有关。也许可以通过使用“同步上下文”将“IsBusy”属性设置回false来解决问题。 - Raúl Otaño
此外,您必须添加DataContext项的代码。 - Raúl Otaño
@RaulOtaño 我认为你是对的。我做了一个小的示例应用程序,没有使用异步,指示器的行为符合我的预期。我正在使用BackgroundWorker来进行WebService调用。busy在DoWork()方法中被设置为true,在回调方法中通过RunWorkerCompleted()方法传递给类并启动时被设置为false。process在RunWorkerAsync()中触发。我以为RunWorkerCompleted会自动在UI线程中运行?还是我需要做一些特殊的事情?我会发布一些示例代码。 - Crudler
如果有帮助的话,UI位于由Navigate方法设置为我的用户控件实例的框架内。 - Crudler
1个回答

0

我想我解决了它。 通过上面发布示例代码(删除所有我的测试杂乱无章)似乎解决了它,这通常是情况。

好的,模型可以工作,但因为我正在与Web服务交谈,并且在第一次调用后,我的WebService调用非常快,之后速度太快,以至于我看不到繁忙指示器。

所以为了绕过这个问题......我变得懒惰并添加了一个睡眠。但是我将睡眠放在回调中。因此,由于回调在UI线程中触发,它在错误的点阻塞了。繁忙指示器已经出现和消失,而它还没有到达睡眠。

所以我将它移动到DoWork方法中(该方法位于ui threqad之外),繁忙指示器保持不变。

我真傻。感谢各位的建议!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接