无法从后台工作线程更新图像绑定



我得到:

"类型的未处理异常 "System.Windows.Markup.XamlParseException" 发生在 演示框架.dll

其他信息:必须在与 相同的线程上创建依赖项源 依赖对象。

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 中返回一个列表,该列表可以正常显示名称。我还做了一个测试方法,该方法不使用后台工作者来验证它是否正常工作。我也尝试调用主线程,但仍然收到相同的错误。我不确定接下来要尝试什么。

如果 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;
}

尝试在集合上设置 EnableCollectionSync

BindingOperations.EnableCollectionSynchronization(AutoList, _itemsLock);

然后在您的 worker 方法中对其进行 clear() 和 Add(),而不是重新创建它

最新更新