Reputation: 33
I am getting:
"An unhandled exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Additional information: Must create DependencySource on same Thread as the 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>
ViewModel:
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");
}
Model:
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;
}
}
If I remove the binding of the image from the XAML file, I get back a list in the UI that displays the names fine. I also did a test method that didn't use a backgroundworker to verify that it worked correctly. I also tried invoking the main thread and still got the same error. I am unsure of what to try next.
Upvotes: 0
Views: 496
Reputation: 128136
If the image parameter refers to a local file, it should be sufficient to specify that the BitmapImage is loaded immediately by setting BitmapCacheOption.OnLoad
, and then freeze it.
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;
}
In case it's a remote resource you may first download the image buffer and put it into a MemoryStream, from which you finally load the image:
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;
}
Upvotes: 1
Reputation: 1310
try setting EnableCollectionSynchronization on your collection
BindingOperations.EnableCollectionSynchronization(AutoList, _itemsLock);
and then clear() and Add() to it in your worker method instead of recreating it
Upvotes: 1