none
Problem mit ListView Items RRS feed

  • Frage

  • Hallo

    ich habe eine ListView mit 2 Spalten. Die Spalten sind mittels Binding an eine Item Klasse gebunden. Das ListView Control ist mit einem Container in eine Windows Form eingebttet.

    Jetzt füge ich von der Form items in die ListView ein, indem ich mir eine neue Item Klasse hole und dann anfüge. Das klappt ohne Problem. Ich kann jetzt auf ein Item klicken und das Item wird mir angezeigt.

    LV1.Items.Add(new itemclass()  {.test="Item 1"})

    Wenn ich mir ein Item aus einer anderen Item Class heranziehe und die dann einfuegen will dann bekomme ich eine Fehlermeldung, sobald ich auf ein Item klicke.

    Also ich habe eine DLL die mir ein Array von einer Objectklasse zurückgibt.  Diese möchte ich anzeigen lassen.

    For Each q In qq
       Dim op As New myItemClass() With {.MediaContent = q.ItemName, .MediaType = q.ItemType}
       Control1._ItemAdd(op)
    Next

    Sobald ich auf ein Item klicke mit diesem Code

     Private Sub LB1_PreviewMouseDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles LB1.PreviewMouseDown
            Dim temp2 As Integer = itemindex
    
            Dim clickedToDoItem As myItemClass
    
            Dim dep As DependencyObject = CType(e.OriginalSource, DependencyObject)
            Do While dep IsNot Nothing AndAlso Not TypeOf (dep) Is ListViewItem
     -------->           dep = VisualTreeHelper.GetParent(dep)
            Loop
            If dep Is Nothing Then
                Return
            Else
                clickedToDoItem = CType(Me.LB1.ItemContainerGenerator.ItemFromContainer(dep), myItemClass)
                itemindex = Me.LB1.ItemContainerGenerator.IndexFromContainer(dep)
    
     End If

    dann erhalte ich diese Meldung. Woran liegt denn das?? Wie kann ich das verhindern?

    System.InvalidOperationException was unhandled
      Message="'System.Windows.Documents.Run' is not a Visual or Visual3D."
      Source="PresentationCore"
      StackTrace:
           at MS.Internal.Media.VisualTreeUtils.AsVisual(DependencyObject element, Visual& visual, Visual3D& visual3D)
           at MS.Internal.Media.VisualTreeUtils.AsNonNullVisual(DependencyObject element, Visual& visual, Visual3D& visual3D)
           at System.Windows.Media.VisualTreeHelper.GetParent(DependencyObject reference)
           at LCARS_ListView_Control.LCARS_Control.LB1_PreviewMouseDown(Object sender, MouseButtonEventArgs e) in C:\Users\Snecx\Documents\Visual Studio 2008\Projects\Archos9\LCARS_ListView_Control\LCARS_Control.xaml.vb:line 60
           at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
           at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
           at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
           at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
           at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
           at System.Windows.ContentElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
           at System.Windows.Input.InputManager.ProcessStagingArea()
           at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
           at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
           at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
           at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
           at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
           at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
           at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
           at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
           at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
           at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
           at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
           at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
           at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.Run(ApplicationContext context)
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
           at paint.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
           at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException:

     

    Mittwoch, 14. April 2010 19:38

Antworten

  • Ich habe deine Frage mal ganz anders gelöst und habe dann keine Probleme mit einer fremden Klasse.

    XAML-Demo:

    <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"
        xmlns:my="clr-namespace:WpfApplication1">
     <Window.Resources>
      <my:ViewModel x:Key="vm" />
     </Window.Resources>
     <StackPanel DataContext="{Binding Source={StaticResource vm}}">
      <ListView ItemsSource="{Binding Liste}" my:ViewModel.Prop3a="True">
       <ListView.View>
        <GridView>
         <GridViewColumn Header="MediaContent" DisplayMemberBinding="{Binding MediaContent}" />
         <GridViewColumn Header="MediaType" DisplayMemberBinding="{Binding MediaType}" />
        </GridView>
       </ListView.View>
      </ListView>
     </StackPanel>
    </Window>

    Dazu die externe Klasse ViewModel:

    Imports System.ComponentModel
    Imports System.Collections.ObjectModel
    
    Public Class ViewModel
     Implements INotifyPropertyChanged
    
     Public Property Liste As ObservableCollection(Of Datenobjekt)
    
     Public Sub New()
      Liste = New ObservableCollection(Of Datenobjekt)
      Liste.Add(New Datenobjekt With {.MediaContent = "Content 1", .MediaType = "Type 1", .Url = "URL 1"})
      Liste.Add(New Datenobjekt With {.MediaContent = "Content 2", .MediaType = "Type 2", .Url = "URL 2"})
      Liste.Add(New Datenobjekt With {.MediaContent = "Content 3", .MediaType = "Type 3", .Url = "URL 3"})
     End Sub
    
     Public Event PropertyChanged(ByVal sender As Object, _
         ByVal e As System.ComponentModel.PropertyChangedEventArgs) _
         Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
     Public Shared Function GetProp3a(ByVal obj As DependencyObject) As Boolean
      Return CType(obj.GetValue(Prop3aProperty), Boolean)
     End Function
    
     Public Shared Sub SetProp3a(ByVal obj As DependencyObject, ByVal value As Boolean)
      obj.SetValue(Prop3aProperty, value)
     End Sub
    
     Public Shared ReadOnly Prop3aProperty As DependencyProperty = _
       DependencyProperty.RegisterAttached("Prop3a", _
                         GetType(Boolean), _
                         GetType(Label), _
                         New UIPropertyMetadata(False, AddressOf OnProp3a))
    
     Private Shared Sub OnProp3a(ByVal depObj As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
      Dim lv = TryCast(depObj, ListView)
      If lv Is Nothing Then Exit Sub
      If e.NewValue.GetType IsNot GetType(Boolean) Then Exit Sub
      If CType(e.NewValue, Boolean) Then
       AddHandler lv.PreviewMouseDown, AddressOf OnLvPreviewMouseDown
      Else
       RemoveHandler lv.PreviewMouseDown, AddressOf OnLvPreviewMouseDown
      End If
     End Sub
    
     Private Shared Sub OnLvPreviewMouseDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
      If e.OriginalSource.GetType Is GetType(TextBlock) _
         AndAlso CType(e.OriginalSource, TextBlock).DataContext.GetType Is GetType(Datenobjekt) Then
       Dim url = CType(CType(e.OriginalSource, TextBlock).DataContext, Datenobjekt).Url
       MsgBox(url)
      End If
     End Sub
    
    End Class
    
    ''' <summary>
    ''' Datenobjekt-Klasse
    ''' </summary>
    ''' <remarks></remarks>
    Public Class Datenobjekt
     Property MediaContent As String
     Property MediaType As String
     Property Url As String
    End Class
    --
    Peter
    Dienstag, 27. April 2010 07:19

Alle Antworten

  • Hallo Snecx,

    Vielleicht kann man vorher prüfen ob das ein Visual oder Visual 3D Objekt ist bevor die Methode rufen:

      Do While dep IsNot Nothing AndAlso Not TypeOf (dep) Is ListViewItem
       '//dep = VisualTreeHelper.GetParent(dep)
       If TypeOf (dep) Is Visual OrElse TypeOf (dep) Is System.Windows.Media.Media3D.Visual3DThen Then
        dep = VisualTreeHelper.GetParent(dep)
       Else
        Exit Do
       End If
      Loop

     

    Grüße,

    Robert

     

    Donnerstag, 15. April 2010 14:35
    Moderator
  • Hallo

    Danke. Jetzt gehts erstmal weiter aber jetzt bricht er beim zuweisen des Items ab da das interne Object nicht zu meiner myitemclass gecasted werden kann.

    So komme ich leider nicht weiter.

     

    Donnerstag, 15. April 2010 16:09
  • Grml

    jetzt habe ich das so verändert das die Daten nicht mehr aus einer externen DLL kommen sondern aus der eigenen Klasse aus einer simplen Funktion.

    Das geht wieder

    DIM tmp as STRING = "Dies ist ein Test"

    dann kann ich auf das ListViewItem klicken.

    weise ich aber das so zu dann geht es wieder mit dem gleichen Fehler nicht.

    DIM tmp as STRING = GetTitel(URL,"titel")
    Gibt es noch einen anderen weg an ein angeklickted Item zu kommen als den den ich hier verwende?
    Donnerstag, 15. April 2010 16:47
  • Ich habe deine Frage mal ganz anders gelöst und habe dann keine Probleme mit einer fremden Klasse.

    XAML-Demo:

    <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"
        xmlns:my="clr-namespace:WpfApplication1">
     <Window.Resources>
      <my:ViewModel x:Key="vm" />
     </Window.Resources>
     <StackPanel DataContext="{Binding Source={StaticResource vm}}">
      <ListView ItemsSource="{Binding Liste}" my:ViewModel.Prop3a="True">
       <ListView.View>
        <GridView>
         <GridViewColumn Header="MediaContent" DisplayMemberBinding="{Binding MediaContent}" />
         <GridViewColumn Header="MediaType" DisplayMemberBinding="{Binding MediaType}" />
        </GridView>
       </ListView.View>
      </ListView>
     </StackPanel>
    </Window>

    Dazu die externe Klasse ViewModel:

    Imports System.ComponentModel
    Imports System.Collections.ObjectModel
    
    Public Class ViewModel
     Implements INotifyPropertyChanged
    
     Public Property Liste As ObservableCollection(Of Datenobjekt)
    
     Public Sub New()
      Liste = New ObservableCollection(Of Datenobjekt)
      Liste.Add(New Datenobjekt With {.MediaContent = "Content 1", .MediaType = "Type 1", .Url = "URL 1"})
      Liste.Add(New Datenobjekt With {.MediaContent = "Content 2", .MediaType = "Type 2", .Url = "URL 2"})
      Liste.Add(New Datenobjekt With {.MediaContent = "Content 3", .MediaType = "Type 3", .Url = "URL 3"})
     End Sub
    
     Public Event PropertyChanged(ByVal sender As Object, _
         ByVal e As System.ComponentModel.PropertyChangedEventArgs) _
         Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
     Public Shared Function GetProp3a(ByVal obj As DependencyObject) As Boolean
      Return CType(obj.GetValue(Prop3aProperty), Boolean)
     End Function
    
     Public Shared Sub SetProp3a(ByVal obj As DependencyObject, ByVal value As Boolean)
      obj.SetValue(Prop3aProperty, value)
     End Sub
    
     Public Shared ReadOnly Prop3aProperty As DependencyProperty = _
       DependencyProperty.RegisterAttached("Prop3a", _
                         GetType(Boolean), _
                         GetType(Label), _
                         New UIPropertyMetadata(False, AddressOf OnProp3a))
    
     Private Shared Sub OnProp3a(ByVal depObj As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
      Dim lv = TryCast(depObj, ListView)
      If lv Is Nothing Then Exit Sub
      If e.NewValue.GetType IsNot GetType(Boolean) Then Exit Sub
      If CType(e.NewValue, Boolean) Then
       AddHandler lv.PreviewMouseDown, AddressOf OnLvPreviewMouseDown
      Else
       RemoveHandler lv.PreviewMouseDown, AddressOf OnLvPreviewMouseDown
      End If
     End Sub
    
     Private Shared Sub OnLvPreviewMouseDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
      If e.OriginalSource.GetType Is GetType(TextBlock) _
         AndAlso CType(e.OriginalSource, TextBlock).DataContext.GetType Is GetType(Datenobjekt) Then
       Dim url = CType(CType(e.OriginalSource, TextBlock).DataContext, Datenobjekt).Url
       MsgBox(url)
      End If
     End Sub
    
    End Class
    
    ''' <summary>
    ''' Datenobjekt-Klasse
    ''' </summary>
    ''' <remarks></remarks>
    Public Class Datenobjekt
     Property MediaContent As String
     Property MediaType As String
     Property Url As String
    End Class
    --
    Peter
    Dienstag, 27. April 2010 07:19