archimed01

Hi,

I have started a little image browser with wpf.
An ObservableCollection is binded to a Listview

This ObservableCollection (of a personalized class) have 2 DependencyProperty (PathProperty as Uri, and ImgProperty as Bitmapimage).

I create a thread who browse the ObservableCollection and, for each item, create a bitmapImage with PathProperty , and set the ImgProperty with this bitmapimage.

Code Snippet

For Each itm As itemW In instance
Dim img As New BitmapImage
img.BeginInit()
img.CacheOption = BitmapCacheOption.OnLoad
img.CreateOptions = BitmapCreateOptions.IgnoreColorProfile
img.DecodePixelWidth = 120
img.UriSource = itm.Chemin 'ERROR inter thread
img.EndInit()
itm.Image = img 'ERROR inter thread

Next



But that don't work, Inter thread operation error.

I have finded a solution , to use DispatcherOperationCallback but that don't work very well.

For the PathProterty get :
...
Code Snippet

Get

return me.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, New Windows.Threading.DispatcherOperationCallback(AddressOf test), PathProperty)
End Get

Function testtt1(ByVal value As Object) As Object
Return GetValue(value)
End Function



That's work , i can get the PathProperty in the thread.

But with the ImgProperty, that don't work !
In the thread if i set the created bitmapimage i have an inter thread error

The ImgPropertySet :

Code Snippet

Set

Me.Dispatcher.BeginInvoke(Windows.Threading.DispatcherPriority.Background, New Windows.Threading.DispatcherOperationCallback(AddressOf test2), value)

End Set



Function test2(ByVal value As Object) As Object
SetValue(ImgProperty, value)
Return Nothing
End Function




Could you Help Me
Thanks for you help

Excuse me i'm french and i don't speak english very well.


Re: Windows Presentation Foundation (WPF) DependencyProperty DataBinding and Thread

Wolf Schmidt - MSFT

It seems like you need better separation of your ObservableCollection data and your UI, and that you are doing something within ObservableCollection logic (the data domain) that is holding up the UI thread.

Probably the better approach is that your ListView should use a DataTemplate, which in turn references your Path and Image properties as bound values from the ObservableCollection.





Re: Windows Presentation Foundation (WPF) DependencyProperty DataBinding and Thread

archimed01

I don't know if i'm clearly.

The ListView already use this DataTemplate :


Code Snippet
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="3" >
<Border Background="#44000000" CornerRadius="3" BorderBrush="White" BorderThickness="2" Height="100" Width="100" >

<Image Source="{Binding Path=Img}" > </Image>
</Border>


<Border CornerRadius="3" Background="LightSteelBlue">
<TextBlock Text="{Binding Path=Path, Converter={StaticResource Uri_tofilename} }"> </TextBlock>
</Border>

</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>


The itemW class

Code Snippet

Public Class itemW
Inherits DependencyObject

Public Shared PathProperty As DependencyProperty = DependencyProperty.Register("Path", GetType(Uri), GetType(itemW))
Public Shared ImgProperty As DependencyProperty = DependencyProperty.RegisterAttached("Img", GetType(BitmapImage), GetType(itemW))




Public Property Img() As BitmapImage
Get
Return Me.GetValue(ImgProperty)
End Get

Set(ByVal value As BitmapImage)
Me.Dispatcher.BeginInvoke(Windows.Threading.DispatcherPriority.Background, New Windows.Threading.DispatcherOperationCallback(AddressOf test2), value)

End Property



Function test2(ByVal value As Object) As Object
SetValue(ImageProperty, value)
Return Nothing
End Function





Public Property Path() As Uri
Get
Return Me.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, New Windows.Threading.DispatcherOperationCallback(AddressOf test), PathProperty)


End Get

Set(ByVal value As Uri)
Me.SetValue(PathProperty, value)
End Set
End Property


Function test(ByVal no As Object) As Object
Return GetValue(no)
End Function


Enc Class



When user click :
i create ObservableCollection (of itemw)

instance = New System.Collections.ObjectModel.ObservableCollection(Of itemW)()

I browse a directory, get file uri and create the itemw ( i only set the PathProperty)
and fill the ObservableCollection.
Listview1.source = instance


And after for generate thumb i start the thread (but don't work)

Code Snippet

For Each itm As itemW In instance
Dim img As New BitmapImage
img.BeginInit()
img.CacheOption = BitmapCacheOption.OnLoad
img.CreateOptions = BitmapCreateOptions.IgnoreColorProfile
img.DecodePixelWidth = 120
img.UriSource = itm.Chemin 'ERROR inter thread
img.EndInit()
itm.Image = img 'ERROR inter thread

Next









Re: Windows Presentation Foundation (WPF) DependencyProperty DataBinding and Thread

Wolf Schmidt - MSFT

Have you already tried creating the dependency between Img and Path by using PropertyChangedCallbacks on one or both dependency properties That wouldn't require doing anything with threading. The code that you run when creating your ObservableCollection would trigger the change and the property system would do the work for you from then on.



Re: Windows Presentation Foundation (WPF) DependencyProperty DataBinding and Thread

archimed01

If i use PropertyChangedCallbacks (for create bitmapimage when the uri is changed) the bitmapimage is creating in the UI thread and the UI is not responding




Re: Windows Presentation Foundation (WPF) DependencyProperty DataBinding and Thread

WPCoder

I'm not following exactly what the problem is here -- but two suggestions:

Take a look at a sample project I created a while back that does a bunch of bitmap manipulations, in threads, etc, all for the purpose of showing them in a ListBox. Some images contain thumbnails already, and if you can use those, it's a lot faster than creating them in code using the DecodePixelHeight/Width properties.

http://www.wiredprairie.us/journal/2007/04/photoscroll_the_worst_named_wp.html

Other thought was to Freeze the bitmap image your creating, if it's being created in another thread. If you don't, the main UI can't access it.






Re: Windows Presentation Foundation (WPF) DependencyProperty DataBinding and Thread

archimed01

"Other thought was to Freeze the bitmap image your creating, if it's being created in another thread. If you don't, the main UI can't access it."


Thanks a lot !

In the thread i just freeze the bitmap ,
and now that's work