无法从BackgroundWorker更新图像绑定

时间:2015-03-13 01:03:39

标签: c# wpf mvvm backgroundworker mvvm-light

我得到了:

  

“未处理的类型异常   'System.Windows.Markup.XamlParseException'发生在   PresentationFramework.dll

     

附加信息:必须在同一个Thread上创建DependencySource   DependencyObject。“

XAML:

  <ListBox x:Name="AutoListBox" ItemsSource="{Binding AutoList}" Visibility="{Binding AutoListVisibility}">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                   <EventSetter Event="MouseDoubleClick" Handler="EventSetter_OnHandler"></EventSetter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="5"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Image Source="{Binding ImgSource}"></Image>
                        <Label Content="{Binding Name}"></Label>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

视图模型:

    private Visibility isBusyVisibility;

    public Visibility IsBusyVisibility
    {
        get { return isBusyVisibility; }
        set
        {
            isBusyVisibility = value;
            RaisePropertyChanged("IsBusyVisibility");
        }
    }

    private ObservableCollection<GenericPictureName> autoList;

    public ObservableCollection<GenericPictureName> AutoList
    {
        get { return autoList; }
        set
        {
            autoList = value;
            RaisePropertyChanged("AutoList");
        }
    }
public AutoAlbumTrackAssociationViewModel()
    {
        _bwArtist = new BackgroundWorker();
        _bwArtist.DoWork += bwArtist_DoWork;
    }

private void bwArtist_DoWork(object sender, DoWorkEventArgs e)
    {
        AutoList = new ObservableCollection<GenericPictureName>(LastFMLookup.ArtistQuery(e.Argument.ToString()));

        RaisePropertyChanged("AutoList");
        RaisePropertyChanged("IsBusyVisibility");
    }

型号:

public class GenericPictureName
{
    private string name;

    public string Name
    {
        get { return name; }
        set
        {
            name = value;
        }
    }

    private ImageSource imgSource;

    public ImageSource ImgSource
    {
        get { return imgSource; }
        set
        {
            imgSource = value;
        }
    }


    public GenericPictureName()
    {

    }

    public GenericPictureName(string name, string image)
    {
        Name = name;
        var bitmapImage = new BitmapImage();
        bitmapImage.BeginInit();
        bitmapImage.UriSource = new Uri(image); ;
        bitmapImage.EndInit();
        ImgSource = bitmapImage;
    }

}

如果我从XAML文件中删除图像的绑定,我会在UI中找回显示名称的列表。我还做了一个测试方法,没有使用backgroundworker来验证它是否正常工作。我也试过调用主线程仍然得到相同的错误。我不确定下一步该尝试什么。

2 个答案:

答案 0 :(得分:0)

如果image参数引用本地文件,则应通过设置BitmapCacheOption.OnLoad指定立即加载BitmapImage,然后将其冻结。

public GenericPictureName(string name, string image)
{
    Name = name;
    var bitmapImage = new BitmapImage();
    bitmapImage.BeginInit();
    bitmapImage.UriSource = new Uri(image);
    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    bitmapImage.EndInit();
    bitmapImage.Freeze();
    ImgSource = bitmapImage;
}

如果它是远程资源,您可以先下载图像缓冲区并将其放入MemoryStream中,最后从中加载图像:

public GenericPictureName(string name, string image)
{
    Name = name;
    var bitmapImage = new BitmapImage();
    var imageBuffer = new WebClient().DownloadData(image);
    using (var ms = new MemoryStream(imageBuffer))
    {
        bitmapImage.BeginInit();
        bitmapImage.StreamSource = ms;
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.EndInit();
    }
    bitmapImage.Freeze();
    ImgSource = bitmapImage;
}

答案 1 :(得分:0)

尝试在集合上设置EnableCollectionSynchronization

BindingOperations.EnableCollectionSynchronization(AutoList, _itemsLock);

然后在您的worker方法中清除()和Add()而不是重新创建它