FileSystemWatcherを使用して、ディレクトリに追加された他のPNG画像を自動的に追加するObservableCollectionがあります。 ListBoxには、次のXAMLを使用してPhotosオブジェクトにバインドされたItemsSourceデータがあります。 PNGファイルが監視対象ディレクトリに追加されたときにObservableCollection FileSystemWatcher ListBox更新の問題
<ListBox ItemsSource="{Binding Source={StaticResource Photos}}" IsSynchronizedWithCurrentItem="True"/>
しかしOnPhotoCreatedイベントは、しかし、ListBoxのUIが更新されていない(ブレークポイントはこれを確認し)と呼ばれています。何か案は?
Public Class Photos
Inherits Collections.ObjectModel.ObservableCollection(Of BitmapImage)
' Events
Public Event ItemsUpdated As EventHandler
' Fields
Private FileSystemWatchers As Dictionary(Of String, FileSystemWatcher) = New Dictionary(Of String, FileSystemWatcher)
' Methods
Protected Overrides Sub ClearItems()
MyBase.ClearItems()
Me.FileSystemWatchers.Clear()
End Sub
Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As BitmapImage)
MyBase.InsertItem(index, item)
Dim ImagePath As String = IO.Path.GetDirectoryName(item.UriSource.LocalPath)
If Not Me.FileSystemWatchers.ContainsKey(ImagePath) Then
Dim FileWatcher As New FileSystemWatcher(ImagePath, "*.png")
FileWatcher.EnableRaisingEvents = True
AddHandler FileWatcher.Created, New FileSystemEventHandler(AddressOf Me.OnPhotoCreated)
AddHandler FileWatcher.Deleted, New FileSystemEventHandler(AddressOf Me.OnPhotoDeleted)
AddHandler FileWatcher.Renamed, New RenamedEventHandler(AddressOf Me.OnPhotoRenamed)
Me.FileSystemWatchers.Add(ImagePath, FileWatcher)
End If
End Sub
Private Sub OnPhotoCreated(ByVal sender As Object, ByVal e As FileSystemEventArgs)
MyBase.Items.Add(New BitmapImage(New Uri(e.FullPath)))
RaiseEvent ItemsUpdated(Me, New EventArgs)
End Sub
Private Sub OnPhotoDeleted(ByVal sender As Object, ByVal e As FileSystemEventArgs)
Dim index As Integer = -1
Dim i As Integer
For i = 0 To MyBase.Items.Count - 1
If (MyBase.Items.Item(i).UriSource.AbsolutePath = e.FullPath) Then
index = i
Exit For
End If
Next i
If (index >= 0) Then
MyBase.Items.RemoveAt(index)
End If
RaiseEvent ItemsUpdated(Me, New EventArgs)
End Sub
Private Sub OnPhotoRenamed(ByVal sender As Object, ByVal e As RenamedEventArgs)
Dim index As Integer = -1
Dim i As Integer
For i = 0 To MyBase.Items.Count - 1
If (MyBase.Items.Item(i).UriSource.AbsolutePath = e.OldFullPath) Then
index = i
Exit For
End If
Next i
If (index >= 0) Then
MyBase.Items.Item(index) = New BitmapImage(New Uri(e.FullPath))
End If
RaiseEvent ItemsUpdated(Me, New EventArgs)
End Sub
End Class
更新#1:以下に示すように、私は、イベントを試してみました。そのため、InvalidOperationException、 "別のスレッドが所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません"というクラッシュが発生します。新しいイメージをスクロールして表示しようとすると、 Refreshメソッドが必要ないと私は望んでいました。
Dim Photos As Photos = CType(Me.FindResource("Photos"), Photos)
AddHandler Photos.ItemsUpdated, AddressOf Me.Photos_ItemsUpdated
Private Sub RefreshPhotos()
'
If Me.ImageListBox.Dispatcher.CheckAccess = True Then
Me.ImageListBox.Items.Refresh()
Else
Dispatcher.BeginInvoke(DispatcherPriority.Normal, New DispatcherMethodCallback(AddressOf Me.RefreshPhotos))
End If
'
End Sub
Private Sub Photos_ItemsUpdated(ByVal sender As Object, ByVal e As EventArgs)
'
Debug.WriteLine("PhotosUpdated")
Me.RefreshPhotos()
'
End Sub
RaiseEvent ItemsUpdatedへの呼び出しがありますが、そのイベントで何かしていることはわかりません。何か不足していますか? – David
私はそのイベントを試みましたが、期待どおりに動作しませんでした。私はPhotosクラスでリフレッシュを呼び出す必要がない何かをやりたいと思っていました。 – Luke
上記のコードでUpdate#1を参照してください。 – Luke