开发者

WPF ScatterView binding to multiple sources

I am using a ScatterView and am currently binding to a folder so that when my app starts up some sample images are displayed, this works great.

<s:ScatterView x:Name="MainScatterView">
        <s:ScatterView.ItemTemplate>
            <DataTemplate>
                <Image Source="{Binding}"/>
            </DataTemplate>
        </s:ScatterView.ItemTemplate>
    </s:ScatterView>

I then set the binding using

 scatter.ItemsSource =
                System.IO.Directory.GetFiles(imagesPath, "*.jpg");

This works great but then when I try add further images:

Image img = new Image();
        img.Source =
            new BitmapImage(new Uri("\\Resources\\Koala.jpg", UriKind.Relative));
        scatter.Items.Add(img);

I get an InvalidOperationException: Operation not valid when ItemSource is in use.

What is the best way to handle this. Remove the binding and add the im开发者_如何学编程ages manually on startup? I'm assuming then since the ItemSource is the same any further additions wont cause any problems? Or is there a better way to handle this since the binding method works really well.

cheers


This calls for a ViewModel

This type of problem, binding working well for the simple case but starting to fall down as you add scenarios, is a great indicator that it's time to use Model - View - ViewModel.

Roughly speaking, the idea is that you have a View (your XAML) and a Model (your data, in this case a set of files). But instead of directly binding the View to the Data, you add an intermediate class called the ViewModel. Your View binds to the ViewModel and your ViewModel loads itself from the Model. This gives you wiggle room to do more than simple things when loading data to be bound.

What does that mean here? It would look like:

public class MainViewModel
{
    // ObservableCollection adds databinding goodness so when you add a new file,
    // the UI automatically refreshes
    public ObservableCollection<string> Images { get; private set; }

    public MainViewModel(string path)
    {
        Images = new ObservableCollection<string>();
        Images.AddRange(Directory.GetFiles(path, "*.jpg"));
    }

    public void AddImage(string path)
    {
        Images.Add(path);
    }
}

and now in your xaml, you set your datacontext to new MainViewModel. You can do this in code behind or using a StaticResource, if you use a StaticResource you need a ctor that takes no parameters so you'll have to set your initial directory in some other way. Your binding then looks like:

<Image Source={Binding Images} />

Take a good look at the M-V-VM pattern. You'll find that it makes databinding problems like this easier and also has a host of other benefits like fewer event handlers (so fewer reference leaks), better testability, easier to work with Blend, and easier to add new types of UI technologies.


I'm also new to Surface development, anyway what I have is remove the databinding and add the images manually via a for loop.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜