Just a quick little question: When developing a WPF MVVM application, is there any situation where you would use the Dispatcher?
I haven't actually used the Dispatcher before, but it seems like its only used when your code actually needs to access a Control. However, the MVVM pattern tells me to never reference the view under any circumstance(databinding aside?). That means that the only place I would use the Dispatcher is in the code-behind for animation effects.
Therefore, in a WPF MVVM application, you never use the dispatcher and, in my case, I shouldn't take the time to learn about it at the moment?
The only time I could see it being used is to run a method on the VM when the application is idle, although, in that case, you still wouldn't care about being able to reference the UI thread.
WPF Dispatcher and MVVM
Page 1 of 12 Replies - 2337 Views - Last Post: 27 February 2012 - 04:06 PM
Replies To: WPF Dispatcher and MVVM
#2
Re: WPF Dispatcher and MVVM
Posted 24 February 2012 - 03:53 AM
There isn't much to learn in Dispatcher so I would recommend learning it, since it wouldn't take much of your time and might help you later on. Basically it is quite like Invoke method in every control in WinForms.
Hmm? Try executing the following code. It has another thread doing all the work which could be the background thread you were talking about:
xaml:
code behind:
You should receive error: "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread."
So you need some kind of a reference to the UI thread. What I usually do is I take System.Threading.SynchronizationContext of the UI thread and pass it to the viewmodel and use it there:
This works and the VM still remains it's business aspects by not referencing any UI stuff, in theory.
Quote
The only time I could see it being used is to run a method on the VM when the application is idle, although, in that case, you still wouldn't care about being able to reference the UI thread.
Hmm? Try executing the following code. It has another thread doing all the work which could be the background thread you were talking about:
xaml:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox ItemsSource="{Binding Path=Items}" />
<Button Margin="306,183,38,55" Name="Button1" />
</Grid>
</Window>
code behind:
Imports System.Collections.ObjectModel
Class MainWindow
Private viewmodel As ViewModel
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
viewmodel = New ViewModel
Me.DataContext = viewmodel
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
viewmodel.FillItemsAsync()
End Sub
End Class
Public Class ViewModel
Public Sub New()
Me.Items = New ObservableCollection(Of String)
End Sub
Public Sub FillItemsAsync()
Dim thread As New System.Threading.Thread(Sub()
For index = 1 To 10
Me.Items.Add("my new item #" & index)
Next
End Sub)
thread.Start()
End Sub
Private _Items As ObservableCollection(Of String)
Public Property Items() As ObservableCollection(Of String)
Get
Return _Items
End Get
Set(ByVal value As ObservableCollection(Of String))
_Items = value
End Set
End Property
End Class
You should receive error: "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread."
So you need some kind of a reference to the UI thread. What I usually do is I take System.Threading.SynchronizationContext of the UI thread and pass it to the viewmodel and use it there:
Imports System.Collections.ObjectModel
Class MainWindow
Private viewmodel As ViewModel
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
viewmodel = New ViewModel(System.Threading.SynchronizationContext.Current)
Me.DataContext = viewmodel
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
viewmodel.FillItemsAsync()
End Sub
End Class
Public Class ViewModel
Private syncContext As System.Threading.SynchronizationContext
Public Sub New(syncContext As System.Threading.SynchronizationContext)
Me.syncContext = syncContext
Me.Items = New ObservableCollection(Of String)
End Sub
Public Sub FillItemsAsync()
Dim thread As New System.Threading.Thread(Sub()
For index = 1 To 10
Me.syncContext.Post(Sub(i)
Me.Items.Add("my new item #" & i.ToString)
End Sub, index)
Next
End Sub)
thread.Start()
End Sub
Private _Items As ObservableCollection(Of String)
Public Property Items() As ObservableCollection(Of String)
Get
Return _Items
End Get
Set(ByVal value As ObservableCollection(Of String))
_Items = value
End Set
End Property
End Class
This works and the VM still remains it's business aspects by not referencing any UI stuff, in theory.
This post has been edited by janne_panne: 24 February 2012 - 07:43 AM
#3
Re: WPF Dispatcher and MVVM
Posted 27 February 2012 - 04:06 PM
ah....thats the key.
I never realized that modifying the content of the datasource counted as interacting with the control itself.
thanks!
I never realized that modifying the content of the datasource counted as interacting with the control itself.
thanks!
Page 1 of 1
|
|

New Topic/Question
Reply




MultiQuote




|