私を助けたり、より良い方法を示したりできる人に。私は監視可能なコレクション、カスタムクラスに基づくリスト、グローバル/非グローバルコレクション、リストボックスのアイテムソース、同期ロック、そして最後にアイテムを空にして手動で入力することを試みました。
正常に動作する傾向がありますが、「コレクションが変更されました。列挙操作が実行されない可能性があります」というエラーが時々発生します。System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext() で発生するようです
過去数週間にわたっていくつかの異なることを試しましたが、時々それを回避することができますが、別の領域で再現することができます.
基本的に、Parent、Current、Children の 3 つのリストボックスがあります。これらにはキャプション付きの画像があります。画像が選択されると、親、現在、および子の画像が空になり、選択した画像に基づいて再読み込みされます。
私はvbで書いていますが、それが助けになるならC#に変換できます。コードは何度も変更されているため、最新のものにはコメント付きのコードがたくさん含まれています。ヘルプや提案をいただければ幸いです。それを単純化したり、機能させたり、パフォーマンスを向上させたりするのは素晴らしいことです。
3 重のコードを想像してみてください。コードは、名前を除いてほぼ同じです。
<Page.Resources>
<CollectionViewSource
Source="{Binding Source={x:Static Application.Current}, Path=CurrentList}"
x:Key="CurrentList" />
</Page.Resources>
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Disabled" PanningMode="VerticalOnly" FlowDirection="RightToLeft" HorizontalScrollBarVisibility="Auto"
>
<ListBox Name="CurrentListbox" VerticalAlignment ="Stretch" Margin=" 8" Background="Transparent"
Height="Auto" BorderThickness="0" HorizontalContentAlignment="Center" FlowDirection="LeftToRight" HorizontalAlignment="Center"
ItemsSource="{Binding CurrentList}">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="ListBoxItem.Selected" Handler="CurrentListBoxItem_Selected" HandledEventsToo="false"/>
</Style>
</ListBox.Resources>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="#FF0000AC" Style="{StaticResource ResourceKey=ThumbnailBorder}">
<!--<Viewbox MaxWidth ="100" >-->
<StackPanel>
<Grid>
<Border Name="ItemBorder" Style="{StaticResource ResourceKey=ThumbnailInnerBorder}"/>
<Image Name="PersonImage" MaxHeight ="200" MaxWidth ="200" Source="{Binding ProfileImagePath}"
HorizontalAlignment="Center" >
<Image.OpacityMask>
<VisualBrush Visual="{Binding ElementName=ItemBorder}"/>
</Image.OpacityMask>
</Image>
</Grid>
<Viewbox MaxWidth ="190" Margin="5,0,5,0" MaxHeight="15">
<TextBlock Name="Person" Text="{Binding ProfileName}" Tag="{Binding UserID}" HorizontalAlignment="Center" />
</Viewbox>
</StackPanel>
<!--</Viewbox>-->
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
コレクションはグローバル変数に格納され、SQlCe コマンドを使用して入力されます。
Public Shared CurrentPeopleList As New CollectionViewSource
Public Shared Current_People_List As New ObservableCollection(Of Currents)()
Public Shared Property CurrentList() As ObservableCollection(Of Currents)
Get
Return Current_People_List
End Get
Set(ByVal value As ObservableCollection(Of Currents))
Current_People_List = value
End Set
End Property
Currents のカスタム クラス:
Public Class Currents
Implements INotifyPropertyChanged
Private ProfileNameValue As String
Private UserIDValue As Integer
Private ProfileImagePathValue As String
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
#Region "Properties Getters and Setters" Public Property ProfileName() As String Get Return Me.ProfileNameValue End Get Set(ByVal 値 As String) Me.ProfileNameValue = 値 OnPropertyChanged("ProfileName") End Set End プロパティ
Public Property UserID() As Integer
Get
Return Me.UserIDValue
End Get
Set(ByVal value As Integer)
If value < 0 Then
Throw New ArgumentException("User ID must be greater than 0 ")
End If
Me.UserIDValue = value
OnPropertyChanged("UserID")
End Set
End Property
Public Property ProfileImagePath() As String
Get
Return Me.ProfileImagePathValue
End Get
Set(ByVal value As String)
Me.ProfileImagePathValue = RelativeProgramPath() & "Media\Pictures\" & value
OnPropertyChanged("ProfileImagePath")
End Set
End Property
#End Region
Public Sub New(ByVal UserID As Integer, ByVal ProfileName As String, ByVal ProfileImagePath As String)
Me.ProfileNameValue = ProfileName
Me.UserIDValue = UserID
Me.ProfileImagePathValue = If(ProfileImagePath Like "pack://*", ProfileImagePath, RelativeProgramPath() & "Media\Pictures\" & ProfileImagePath)
End Sub
Protected Sub OnPropertyChanged(ByVal name As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
End Sub
End Class
最後に、これらが設定される方法は、共通の関数を使用することです
Private Sub Reload(ByVal CurrentID As Integer)
Try
Try
ParentList = Nothing
CurrentList = Nothing
ChildrenList = Nothing
Catch
End Try
Try
Me.ParentListbox.ItemsSource = Nothing
Me.CurrentListbox.ItemsSource = Nothing
Me.ChildListbox.ItemsSource = Nothing
Catch
End Try
Try
CurrentPersonID = CurrentID
'Load the Images Based on the people.
Dim Ch = Load_Children_People(CurrentID)
Dim C = Load_Current_People(CurrentID)
Dim P = Load_Parent_People(CurrentID)
ParentList = If(P.Count > 0, P, Nothing)
CurrentList = If(C.Count > 0, C, Nothing)
ChildrenList = If(Ch.Count > 0, Ch, Nothing)
Catch
End Try
Try
If ParentList IsNot Nothing Then _
Me.ParentListbox.ItemsSource = CollectionViewSource.GetDefaultView(ParentList)
If CurrentList IsNot Nothing Then _
Me.CurrentListbox.ItemsSource = CollectionViewSource.GetDefaultView(CurrentList)
If ChildrenList IsNot Nothing Then _
Me.ChildListbox.ItemsSource = CollectionViewSource.GetDefaultView(ChildrenList)
Catch
End Try
Catch
End Try
'For some reason this will not work without a pause. Not sure why.
'FIXME Remove Pause Delay When able.
'Thread.Sleep(200)
End Sub
エラーをキャッチするために多くの try-catch を使用しましたが、これまでのところ成功していません。私の疑いは、特定できないUIスレッド中にエラーが発生したことです。先に述べたように。どんな援助も素晴らしいでしょう。