1
votes

I've currently got XAML code like this:

<ListView Name="fileLV" SelectionMode="Extended" ItemsSource="{Binding path=DataContext.SelectedAsset.Files,ElementName=selectionView,IsAsync=True}"/>

That "Files" property takes fifteen seconds to return. The whole time the user is wondering what's going on. I've seen some other code to show the fallback value or use multiple bindings, but those don't rely imply "leave this control alone" like an hourglass over that control would imply.

What I want is to be able name a binding and then bind some other properties to that binding's IsBusy property. I want a trigger to change the cursor on that listview while his binding is busy. Is there any existing WPF framework help for this?

3
Why are you dismissing BackGroundWorker? You can disable the control while the data is loading. ProcessChanged is way more informative than an hour glass - you can update it with % complete or number of files. With Priority binding you cannot disable or show a real status message.paparazzo

3 Answers

0
votes

I don't know of any built-in, out-of-the-box solution but there sure are ways to make a nice experience out of it. I will give you the quick idea of how I would build this and if you need I can come up with the code as well:

  1. Create a "LoadingItem" DataTemplate that would show an progress bar of some kind as an item of your list

  2. Create a "DataTemplateSelector" to switch between the LoadingItem and the RegularItem of your list.

  3. In your Files property, clear the collection and add an item that will be shown as LoadingItem (depends on how you built your DataTemplateSelector logic. Start another thread to scan for files and fill a return the results in a temporary collection (BackgroundWorker). When the method returns, you are on the UI thread again, clear your ItemsSource collection again and fill it with the results.
0
votes

For this do not use IsAsync. On the Property use a BackGroundWorker. First return a source with a "working message", start BackGroundWorker, then on the callback supply the real source and call NotifyPropertyChanged. You can even have a progess bar.

0
votes

I was able to make the DataTemplateSelector work. One caveat was that all the bindings for the ListView need to be enumerable. In my control I added a resource like this:

    <UserControl.Resources>
    <x:Array x:Key="LoadingTemplate" Type="DataTemplate">
    <DataTemplate>...my daisy code...</DataTemplate></x:Array>...

Then I changed my binding to look like this:

                    <ListView.ItemsSource>
                        <PriorityBinding>
                            <Binding Path="DataContext.SelectedAsset.Files" ElementName="selectionView" IsAsync="True"/>
                            <Binding Source="{StaticResource LoadingTemplate}" />
                        </PriorityBinding>
                    </ListView.ItemsSource>

Then I installed this template selector:

    public class OverridableDataTemplateSelector: DataTemplateSelector
    {
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            return item as DataTemplate ?? base.SelectTemplate(item, container);
        }
    }