0

私を助けたり、より良い方法を示したりできる人に。私は監視可能なコレクション、カスタムクラスに基づくリスト、グローバル/非グローバルコレクション、リストボックスのアイテムソース、同期ロック、そして最後にアイテムを空にして手動で入力することを試みました。

正常に動作する傾向がありますが、「コレクションが変更されました。列挙操作が実行されない可能性があります」というエラーが時々発生します。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スレッド中にエラーが発生したことです。先に述べたように。どんな援助も素晴らしいでしょう。

4

0 に答える 0