Ungewollt zwei Instanzen eines ViewModels?

  • WPF MVVM
  • .NET (FX) 4.5–4.8

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von kafffee.

    Ungewollt zwei Instanzen eines ViewModels?

    Hallo an alle,

    ich erzeuge in meinem MainViewModel eine Instanz des LayerViewModel, von dem aus ich Zugriff auf alle ViewModels von (fast) allen anderen ViewModels aus habe. Also ausser die, die ich dynamisch erzeuge.
    Nun möchte ich diese Instanz an einen Service MainModule weitergeben, damit ich auch von meinen dynamisch erzeugten aus Zugriff habe.

    Das sieht wie folgt aus:

    VB.NET-Quellcode

    1. Public Class MainViewModel
    2. Public Sub New()
    3. LayerViewModel = New ViewModel.LayerViewModel
    4. MainModule.LayerVM = LayerViewModel
    5. End Sub
    6. End Class


    Wenn ich das dann von irgendwo aufrufe:

    MainModule.LayerVM.SucheViewModel.Initialisieren()

    Funktioniert das auch und Initialisieren() wird aufgerufen, nur in meiner View zeigt es nach der Initialisierung keine Daten an, obwohl die Daten vorhanden sind, wenn ich einen Haltepunkt mache.

    Meine Vermutung ist also, dass die View an eine andere Instanz von SucheViewModel gebunden ist, als die, die initialsiert wurde.

    Weiss jemand vielleicht, wie ich den Fehler auffinden und beheben kann?
    Da müsste man sich mal das ganze Werk angucken. Mit Bindings kann man ja viel falsch machen.
    Ich arbeite immer mit einem Shared MainViewmodel.
    Von "irgendwo" Initialisieren() aufrufen ist fragwürdig. Man muss ja zusehen, dass jedes zu initialisierende Objekt genau einmal initialisiert - nicht mehr und nicht weniger.
    @ErfinderDesRades

    Ich versuch mal alle relevanten Codezeilen hier wiederzugeben.


    VB.NET-Quellcode

    1. Public Class LayerViewModel
    2. Private Property Suche As ViewModel.SucheViewModel 'hier im LayerViewModel kann man beliebig viele verschiedene ViewModels anlegen, hier mal das Beispiel mit der Suche
    3. Sub New()
    4. Suche = New ViewModel.SucheViewModel(Me)
    5. End Sub
    6. Public ReadOnly Property SucheViewModel() As ViewModel.SucheViewModel
    7. Get
    8. Return Suche
    9. End Get
    10. End Property
    11. End Class


    VB.NET-Quellcode

    1. Public Class MainViewModel
    2. Inherits Instrastructure.ViewModelBase
    3. Private MainModule As Services.IZentraleKlasse = Services.ServiceContainer.GetService(Of Services.IZentraleKlasse) 'das hier ist mein Service, über den ich auf LayerViewModel.Suche zugreifen möchte
    4. Public Property LayerViewModel As ViewModel.LayerViewModel
    5. Public Sub New()
    6. LayerViewModel = New ViewModel.LayerViewModel 'hier und wirklich nur hier wird eine Instanz des LayerViewModel erzeugt, auch nicht im XAML
    7. MainModule.LayerVM = LayerViewModel 'hier möchte ich die Instanz von LayerViewModel an den Service übergeben
    8. ViewModelSuche = LayerViewModel.SucheViewModel
    9. End Sub
    10. End Class


    Und schliesslich:

    VB.NET-Quellcode

    1. Public Class SucheViewModel
    2. Inherits Instrastructure.ViewModelBase
    3. Private Property LayerViewModel As ViewModel.LayerViewModel
    4. Sub New(Parent As ViewModel.LayerViewModel)
    5. LayerViewModel = Parent
    6. 'Initialisieren() 'wenn ich diese Sub aus der Sub New() aufrufe, funktioniert es, aber es würde an anderer Stelle später knallen, diese darf erst ausgeführt werden, wenn das MainWindow komplett geladen ist. Deshalb hab ich sie auskommentiert.
    7. End Sub
    8. Public Sub Initialisieren()
    9. MusikdatenbankLaden_Execute(Nothing)
    10. GeneriereGenreListe()
    11. ErstelleDefault()
    12. End Sub
    13. End Class


    Letztendlich dann:

    VB.NET-Quellcode

    1. Class MainWindow
    2. Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) 'diese sollte ja theoretisch nur ein Mal aufgeruen werden
    3. Dim serv = VamosALaPlayer_3._0.ViewModel.Services.ServiceContainer.GetService(Of IZentraleKlasse)
    4. serv.MainDispatcher = Me.Dispatcher 'den hier brauche ich zwingend, damit Initialisieren() in der SucheViewModel funktioniert
    5. Dim MainModule As IZentraleKlasse = ServiceContainer.GetService(Of IZentraleKlasse) 'hier wieder der Service, über den aufgerufen werden soll
    6. MainModule.LayerVM.SucheViewModel.Initialisieren() 'dieser Aufruf funktioniert, aber die View der SucheViewModel zeigt das Ergebnis nicht an...
    7. End Class


    Und im so genannten MainModule:

    VB.NET-Quellcode

    1. Namespace Services
    2. Public Class ZentraleKlasse
    3. Inherits ViewModel.Instrastructure.ViewModelBase
    4. Implements ViewModel.Services.IZentraleKlasse
    5. Private Property LayerVM As LayerViewModel Implements IZentraleKlasse.LayerVM
    6. End Class


    Das Interface IZentraleKlasse dafür lasse ich jetzt mal weg, das denke ich sollte klar sein...

    Und gestartet wird das Programm so in der Application.xaml.vb:

    VB.NET-Quellcode

    1. Class Application
    2. Private Sub Application_Startup(sender As Object, e As StartupEventArgs) Handles Me.Startup
    3. ViewModel.Services.ServiceContainer.Instance.AddService(Of ViewModel.Services.IZentraleKlasse)(New Services.ZentraleKlasse)
    4. ViewModel.Services.ServiceContainer.Instance.AddService(Of ViewModel.Services.IMainWindowService)(New Services.MainWindowService)
    5. ViewModel.Services.ServiceContainer.GetService(Of ViewModel.Services.IMainWindowService).OpenWindow(1000, 500, "Hauptfenster", Nothing, Me)
    6. End Sub
    7. End Class


    Hier wird der DataContext in der MainWindow.xaml gesetzt:

    XML-Quellcode

    1. ​<Window.DataContext>
    2. <viewmodel:MainViewModel/>
    3. </Window.DataContext>


    Ich hoffe mal das war alles.... :)

    Gruss, kafffee
    Hast du auch gebunden? Ich sehe keine Bindungen, werden dir denn Bindungsfehler gemeldet?(Oben in dem Titlebar-Debug-Dingens)

    Das 2. DIng von Rechts
    Bilder
    • Unbenannt.jpg

      9,25 kB, 366×89, 56 mal angesehen
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    @DTF

    Jou 1 Bindungsfehler hab ich, aber der hat nichts damit zu tun und kommt vor, ob ich jetzt Initialisieren() über die Sub New() oder den Service aufrufe...

    Wenn du das meinst:

    XML-Quellcode

    1. <View:Navigationsleiste Grid.Column="0"/>
    2. <ContentControl Content="{Binding AusgewaehltesViewModel, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Name="MeineRegisterKarten">
    3. <ContentControl.Resources>
    4. <DataTemplate DataType="{x:Type viewmodel:SucheViewModel}">
    5. <View:Suche/>
    6. </DataTemplate>
    7. <DataTemplate DataType="{x:Type viewmodel:PlattendecksViewModel}">
    8. <View:PlattendecksView/>
    9. </DataTemplate>
    10. <DataTemplate DataType="{x:Type viewmodel:EqualizerViewModel}">
    11. <View:EqualizerView/>
    12. </DataTemplate>
    13. <DataTemplate DataType="{x:Type viewmodel:EffectRacksViewModel}">
    14. <View:EffectRacks/>
    15. </DataTemplate>
    16. <DataTemplate DataType="{x:Type viewmodel:SettingsViewModel}">
    17. <View:SettingsView/>
    18. </DataTemplate>
    19. </ContentControl.Resources>
    20. </ContentControl>


    In der Navigationsleiste sind paar Buttons, mir denen man dann die Registerkarten über AusgewaehltesViewModel umschalten kann, die im ContentPresenter dann angezeigt werden, darunter auch mein SucheViewModel
    Da sieht man nur, wie du dem ContentControl sagst, welche View bei welchen Typ von ViewModel verwendet werden soll. Ich sehe auch nur eine Bindung, die hier weniger interessant ist. Zeig mal den XAML von den Views, oder besser häng dein Proekt an.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    Klar. Was hast du vor nachzuschauen? Projekt möchte ich jetzt nicht direkt "as is" hochladen. Müsstest dir sowieso noch 1000 DLLs runterladen.

    Spoiler anzeigen

    Quellcode

    1. <UserControl x:Class="Suche"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    6. xmlns:local="clr-namespace:VamosALaPlayer_3._0.View"
    7. xmlns:viewmodel="clr-namespace:VamosALaPlayer_3._0.ViewModel;assembly=VamosALaPlayer_3._0.ViewModel"
    8. mc:Ignorable="d"
    9. d:DesignHeight="450" d:DesignWidth="800" Name="Suche">
    10. <!--<UserControl.DataContext>
    11. <viewmodel:SucheViewModel/>
    12. </UserControl.DataContext>-->
    13. <Grid Name="grdSuchen" Margin="0,0,0,0">
    14. <Grid.ColumnDefinitions>
    15. <ColumnDefinition Width="25*"/>
    16. <ColumnDefinition Width="25*"/>
    17. <ColumnDefinition Width="25*"/>
    18. <ColumnDefinition Width="25*"/>
    19. </Grid.ColumnDefinitions>
    20. <Grid.RowDefinitions>
    21. <RowDefinition Height="5*"/>
    22. <RowDefinition Height="87.5*"/>
    23. <RowDefinition Height="7.5*"/>
    24. </Grid.RowDefinitions>
    25. <Label Name="lblInterpret" Style="{StaticResource Überschriften}" Grid.Column="0" Grid.Row="0" Content="Interpreten"/>
    26. <Label Name="lblAlben" Style="{StaticResource Überschriften}" Grid.Column="1" Grid.Row="0" Content="Alben"/>
    27. <Label Name="lblMusiktitel" Style="{StaticResource Überschriften}" Grid.Column="2" Grid.Row="0" Content="Musiktitel"/>
    28. <Label Name="lblRadiostreams" Style="{StaticResource Überschriften}" Grid.Column="3" Grid.Row="0" Content="Radiostreams / Audio-CD-Tracks"/>
    29. <ListBox Name="lstInterpreten" ScrollViewer.HorizontalScrollBarVisibility="Hidden" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding AnzuzeigendeInterpreten}" SelectedItem="{Binding AusgewaehlterInterpret, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectionMode="Single" SelectedIndex="{Binding MarkierterInterpret, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsSynchronizedWithCurrentItem="True">
    30. <ListBox.ItemTemplate>
    31. <DataTemplate>
    32. <Grid>
    33. <Grid.ColumnDefinitions>
    34. <ColumnDefinition Width="3*"/>
    35. <ColumnDefinition Width="3*"/>
    36. <ColumnDefinition Width="94*"/>
    37. </Grid.ColumnDefinitions>
    38. <TextBlock Grid.Column="2" Text="{Binding Path=Interpret}" TextTrimming="CharacterEllipsis">
    39. <ToolTipService.ToolTip>
    40. <StackPanel>
    41. <TextBlock Text="{Binding Path=Interpret}"/>
    42. </StackPanel>
    43. </ToolTipService.ToolTip>
    44. </TextBlock>
    45. <Border Name="brdInterpretZuPlaylistZufuegen" Height="{StaticResource listboxitemhoehe}" Grid.Column="0" Style="{DynamicResource Navigationsbuttons}" ToolTip="Füge alle Musiktitel dieses Interpreten der Playlist des gewählten Plattendecks zu..." HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    46. <Border.InputBindings>
    47. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.InterpretZuPlaylistZufuegen, ElementName=lstInterpreten}" CommandParameter="{Binding}"/>
    48. </Border.InputBindings>
    49. <Viewbox Stretch="Uniform">
    50. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M31 12h-11v-11c0-0.552-0.448-1-1-1h-6c-0.552 0-1 0.448-1 1v11h-11c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h11v11c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-11h11c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1z"/>
    51. </Viewbox>
    52. </Border>
    53. <Border Name="brdInterpretAbspielen" Height="{StaticResource listboxitemhoehe}" Grid.Column="1" Style="{DynamicResource Navigationsbuttons}" ToolTip="Spiele alle Musiktitel dieses Interpreten auf dem gewählten Plattendeck ab...">
    54. <Border.InputBindings>
    55. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.InterpretAbspielen, ElementName=lstInterpreten}" CommandParameter="{Binding}"/>
    56. </Border.InputBindings>
    57. <Viewbox Stretch="Uniform">
    58. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M6 4l20 12-20 12z"/>
    59. </Viewbox>
    60. </Border>
    61. </Grid>
    62. </DataTemplate>
    63. </ListBox.ItemTemplate>
    64. </ListBox>
    65. <ListBox Name="lstAlben" ScrollViewer.HorizontalScrollBarVisibility="Hidden" Grid.Column="1" Grid.Row="1" ItemsSource="{Binding AnzuzeigendeAlben}" SelectedItem="{Binding AusgewaehltesAlbum, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectionMode="Single" SelectedIndex="{Binding MarkiertesAlbum, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsSynchronizedWithCurrentItem="True">
    66. <ListBox.ItemTemplate>
    67. <DataTemplate>
    68. <Grid>
    69. <Grid.ColumnDefinitions>
    70. <ColumnDefinition Width="3*"/>
    71. <ColumnDefinition Width="3*"/>
    72. <ColumnDefinition Width="94*"/>
    73. </Grid.ColumnDefinitions>
    74. <TextBlock Text="{Binding Path=Album}" Grid.Column="2" TextTrimming="CharacterEllipsis">
    75. <ToolTipService.ToolTip>
    76. <StackPanel>
    77. <TextBlock Text="{Binding Path=Interpret}"/>
    78. <TextBlock Text="{Binding Path=Album}"/>
    79. </StackPanel>
    80. </ToolTipService.ToolTip>
    81. </TextBlock>
    82. <Border Name="brdAlbumZuPlaylistZufuegen" Height="{StaticResource listboxitemhoehe}" Grid.Column="0" Style="{DynamicResource Navigationsbuttons}" ToolTip="Füge alle Musiktitel dieses Albums der Playlist des gewählten Plattendecks zu..." HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    83. <Border.InputBindings>
    84. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.AlbumZuPlaylistZufuegen, ElementName=lstAlben}" CommandParameter="{Binding}"/>
    85. </Border.InputBindings>
    86. <Viewbox Stretch="Uniform">
    87. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M31 12h-11v-11c0-0.552-0.448-1-1-1h-6c-0.552 0-1 0.448-1 1v11h-11c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h11v11c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-11h11c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1z"/>
    88. </Viewbox>
    89. </Border>
    90. <Border Name="brdAlbumAbspielen" Height="{StaticResource listboxitemhoehe}" Grid.Column="1" Style="{DynamicResource Navigationsbuttons}" ToolTip="Spiele alle Musiktitel dieses Albums auf dem gewählten Plattendeck ab...">
    91. <Border.InputBindings>
    92. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.AlbumAbspielen, ElementName=lstAlben}" CommandParameter="{Binding}"/>
    93. </Border.InputBindings>
    94. <Viewbox Stretch="Uniform">
    95. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M6 4l20 12-20 12z"/>
    96. </Viewbox>
    97. </Border>
    98. </Grid>
    99. </DataTemplate>
    100. </ListBox.ItemTemplate>
    101. </ListBox>
    102. <!--<Popup IsOpen="{Binding MusikTitelPopUpSichtBar}" PlacementTarget="{Binding ElementName=lstMusiktitel}" Placement="Center">
    103. <TextBlock Text="kkp"/>
    104. </Popup>-->
    105. <ListBox Name="lstMusiktitel" ScrollViewer.HorizontalScrollBarVisibility="Hidden" Grid.Column="2" Grid.Row="1" SelectionMode="Single" ItemsSource="{Binding AnzuzeigendeMusiktitel}" SelectedIndex="{Binding MarkierterMusiktitel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    106. <ListBox.ContextMenu>
    107. <ContextMenu OverridesDefaultStyle="True" Style="{StaticResource AlleMusiktitel}"/>
    108. </ListBox.ContextMenu>
    109. <ListBox.ItemTemplate>
    110. <DataTemplate>
    111. <Grid>
    112. <Grid.ColumnDefinitions>
    113. <ColumnDefinition Width="3*"/>
    114. <ColumnDefinition Width="3*"/>
    115. <ColumnDefinition Width="94*"/>
    116. </Grid.ColumnDefinitions>
    117. <TextBlock Text="{Binding Path=Musiktitel}" Grid.Column="2" TextTrimming="CharacterEllipsis">
    118. <ToolTipService.ToolTip>
    119. <StackPanel>
    120. <TextBlock Text="{Binding Path=Tracknummer}"/>
    121. <TextBlock Text="{Binding Path=Interpret}"/>
    122. <TextBlock Text="{Binding Path=Album}"/>
    123. <TextBlock Text="{Binding Path=Musiktitel}"/>
    124. <TextBlock Text="{Binding Path=Dauer}"/>
    125. <TextBlock Text="{Binding Path=Genre}"/>
    126. </StackPanel>
    127. </ToolTipService.ToolTip>
    128. </TextBlock>
    129. <Border Name="brdMusiktitelZuPlaylistZufuegen" Height="{StaticResource listboxitemhoehe}" Grid.Column="0" Style="{DynamicResource Navigationsbuttons}" ToolTip="Füge diesen Musiktitel der Playlist des gewählten Plattendecks zu..." HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    130. <Border.InputBindings>
    131. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.MusiktitelZuPlaylistZufuegen, ElementName=lstMusiktitel}" CommandParameter="{Binding}"/>
    132. </Border.InputBindings>
    133. <Viewbox Stretch="Uniform">
    134. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M31 12h-11v-11c0-0.552-0.448-1-1-1h-6c-0.552 0-1 0.448-1 1v11h-11c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h11v11c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-11h11c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1z"/>
    135. </Viewbox>
    136. </Border>
    137. <Border Name="brdMusiktitelAbspielen" Height="{StaticResource listboxitemhoehe}" Grid.Column="1" Style="{DynamicResource Navigationsbuttons}" ToolTip="Spiele diesen Musiktitel auf dem gewählten Plattendeck ab...">
    138. <Border.InputBindings>
    139. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.MusiktitelAbspielen, ElementName=lstMusiktitel}" CommandParameter="{Binding}"/>
    140. </Border.InputBindings>
    141. <Viewbox Stretch="Uniform">
    142. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M6 4l20 12-20 12z"/>
    143. </Viewbox>
    144. </Border>
    145. </Grid>
    146. </DataTemplate>
    147. </ListBox.ItemTemplate>
    148. <!--<ListBox.ContextMenu>
    149. <ContextMenu>
    150. <MenuItem Header="Füge alle angezeigten Musiktitel der Playlist des gewählten Plattendecks zu..."/>
    151. <MenuItem Header="Spiele alle angezeigten Musiktitel auf dem gewählten Plattendeck ab..."/>
    152. </ContextMenu>
    153. </ListBox.ContextMenu>-->
    154. </ListBox>
    155. <Grid Grid.Column="3" Grid.Row="1">
    156. <Grid.RowDefinitions>
    157. <RowDefinition Height="50*"/>
    158. <RowDefinition Height="50*"/>
    159. </Grid.RowDefinitions>
    160. <ListBox Name="lstRadiostreams" ScrollViewer.HorizontalScrollBarVisibility="Hidden" Grid.Row="0" SelectionMode="Single" ItemsSource="{Binding AnzuzeigendeRadiostreams}" SelectedIndex="{Binding MarkierterRadiostream, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    161. <ListBox.ItemTemplate>
    162. <DataTemplate>
    163. <Grid>
    164. <Grid.ColumnDefinitions>
    165. <ColumnDefinition Width="3*"/>
    166. <ColumnDefinition Width="3*"/>
    167. <ColumnDefinition Width="94*"/>
    168. </Grid.ColumnDefinitions>
    169. <TextBlock Text="{Binding Path=Album}" Grid.Column="2" TextTrimming="CharacterEllipsis">
    170. <ToolTipService.ToolTip>
    171. <StackPanel>
    172. <TextBlock Text="{Binding Path=Album}"/>
    173. <TextBlock Text="{Binding Path=Genre}"/>
    174. </StackPanel>
    175. </ToolTipService.ToolTip>
    176. </TextBlock>
    177. <Border Name="brdRadiostreamZuPlaylistZufuegen" Height="{StaticResource listboxitemhoehe}" Grid.Column="0" Style="{DynamicResource Navigationsbuttons}" ToolTip="Füge diesen Radiostream der Playlist des gewählten Plattendecks zu..." HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    178. <Border.InputBindings>
    179. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.RadiostreamZuPlaylistZufuegen, ElementName=lstRadiostreams}" CommandParameter="{Binding}"/>
    180. </Border.InputBindings>
    181. <Viewbox Stretch="Uniform">
    182. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M31 12h-11v-11c0-0.552-0.448-1-1-1h-6c-0.552 0-1 0.448-1 1v11h-11c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h11v11c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-11h11c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1z"/>
    183. </Viewbox>
    184. </Border>
    185. <Border Name="brdRadiostreamAbspielen" Height="{StaticResource listboxitemhoehe}" Grid.Column="1" Style="{DynamicResource Navigationsbuttons}" ToolTip="Spiele diesen Radiostream auf dem gewählten Plattendeck ab...">
    186. <Border.InputBindings>
    187. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.RadiostreamAbspielen, ElementName=lstRadiostreams}" CommandParameter="{Binding}"/>
    188. </Border.InputBindings>
    189. <Viewbox Stretch="Uniform">
    190. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M6 4l20 12-20 12z"/>
    191. </Viewbox>
    192. </Border>
    193. </Grid>
    194. </DataTemplate>
    195. </ListBox.ItemTemplate>
    196. </ListBox>
    197. <ListBox Name="lstAudioCDs" ScrollViewer.HorizontalScrollBarVisibility="Hidden" Grid.Row="1" SelectionMode="Single" ItemsSource="{Binding AnzuzeigendeAudioCDTracks}" SelectedIndex="{Binding MarkierterCDTrack, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    198. <ListBox.ContextMenu>
    199. <ContextMenu OverridesDefaultStyle="False" Style="{StaticResource AlleCDTracks}"/>
    200. </ListBox.ContextMenu>
    201. <ListBox.ItemTemplate>
    202. <DataTemplate>
    203. <Grid>
    204. <Grid.ColumnDefinitions>
    205. <ColumnDefinition Width="3*"/>
    206. <ColumnDefinition Width="3*"/>
    207. <ColumnDefinition Width="94*"/>
    208. </Grid.ColumnDefinitions>
    209. <TextBlock Text="{Binding Path=Musiktitel}" Grid.Column="2" TextTrimming="CharacterEllipsis">
    210. <ToolTipService.ToolTip>
    211. <StackPanel>
    212. <TextBlock Text="{Binding Path=Dauer}"/>
    213. </StackPanel>
    214. </ToolTipService.ToolTip>
    215. </TextBlock>
    216. <Border Name="brdCDTrackZuPlaylistZufuegen" Height="{StaticResource listboxitemhoehe}" Grid.Column="0" Style="{DynamicResource Navigationsbuttons}" ToolTip="Füge diesen Audio-CD-Track der Playlist des gewählten Plattendecks zu..." HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    217. <Border.InputBindings>
    218. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.AudioCDTrackZuPlaylistZufuegen, ElementName=lstAudioCDs}" CommandParameter="{Binding}"/>
    219. </Border.InputBindings>
    220. <Viewbox Stretch="Uniform">
    221. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M31 12h-11v-11c0-0.552-0.448-1-1-1h-6c-0.552 0-1 0.448-1 1v11h-11c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h11v11c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-11h11c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1z"/>
    222. </Viewbox>
    223. </Border>
    224. <Border Name="brdCDTrackAbspielen" Height="{StaticResource listboxitemhoehe}" Grid.Column="1" Style="{DynamicResource Navigationsbuttons}" ToolTip="Spiele diesen Audio-CD-Track auf dem gewählten Plattendeck ab...">
    225. <Border.InputBindings>
    226. <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.AudioCDTrackAbspielen, ElementName=lstAudioCDs}" CommandParameter="{Binding}"/>
    227. </Border.InputBindings>
    228. <Viewbox Stretch="Uniform">
    229. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M6 4l20 12-20 12z"/>
    230. </Viewbox>
    231. </Border>
    232. </Grid>
    233. </DataTemplate>
    234. </ListBox.ItemTemplate>
    235. </ListBox>
    236. </Grid>
    237. <!--<Grid Name="Suchkriterien" Grid.Row="2" Grid.ColumnSpan="2">-->
    238. <Grid Name="Suchkriterien" Grid.Row="2" Grid.Column="0">
    239. <Grid.RowDefinitions>
    240. <RowDefinition Height="50*"/>
    241. <RowDefinition Height="50*"/>
    242. </Grid.RowDefinitions>
    243. <Grid Grid.Row="0" Grid.Column="0">
    244. <Grid.ColumnDefinitions>
    245. <ColumnDefinition Width="120"/>
    246. <ColumnDefinition Width="*"/>
    247. </Grid.ColumnDefinitions>
    248. <Label Style="{DynamicResource LabelTagInfo}" Content="Volltextsuche:" Grid.Column="0" Foreground="{DynamicResource VordergrundfarbeBrush}" Margin="10, 0, 0, 0"/>
    249. <Grid Grid.Column="1">
    250. <Grid.ColumnDefinitions>
    251. <ColumnDefinition Width="95*"/>
    252. <ColumnDefinition Width="5*"/>
    253. </Grid.ColumnDefinitions>
    254. <TextBox Name="txtMusikDurchsuchen" Grid.Column="0" Margin="10, 4, 10, 4" TextAlignment="Justify"
    255. ToolTip="Gebe einen Suchbegriff ein, um nach Interpreten, Alben, Musiktiteln oder Radiostreams zu suchen..."
    256. Text="{Binding TextFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    257. <!--Text="{Binding TextFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" local:FocusExtension.IsFocused="{Binding SucheFokussiert,Mode=TwoWay}">-->
    258. </TextBox>
    259. <Border Name="brdSucheZuruecksetzen" Height="{StaticResource listboxitemhoehe}" Grid.Column="1" Style="{DynamicResource Navigationsbuttons}" ToolTip="Setze die Suche komplett zurück..." HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0, 0, 10, 0">
    260. <Border.InputBindings>
    261. <MouseBinding MouseAction="LeftClick" Command="{Binding SucheZuruecksetzen}"/>
    262. </Border.InputBindings>
    263. <Viewbox Stretch="Uniform">
    264. <Path Margin="4" Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M31.708 25.708c-0-0-0-0-0-0l-9.708-9.708 9.708-9.708c0-0 0-0 0-0 0.105-0.105 0.18-0.227 0.229-0.357 0.133-0.356 0.057-0.771-0.229-1.057l-4.586-4.586c-0.286-0.286-0.702-0.361-1.057-0.229-0.13 0.048-0.252 0.124-0.357 0.228 0 0-0 0-0 0l-9.708 9.708-9.708-9.708c-0-0-0-0-0-0-0.105-0.104-0.227-0.18-0.357-0.228-0.356-0.133-0.771-0.057-1.057 0.229l-4.586 4.586c-0.286 0.286-0.361 0.702-0.229 1.057 0.049 0.13 0.124 0.252 0.229 0.357 0 0 0 0 0 0l9.708 9.708-9.708 9.708c-0 0-0 0-0 0-0.104 0.105-0.18 0.227-0.229 0.357-0.133 0.355-0.057 0.771 0.229 1.057l4.586 4.586c0.286 0.286 0.702 0.361 1.057 0.229 0.13-0.049 0.252-0.124 0.357-0.229 0-0 0-0 0-0l9.708-9.708 9.708 9.708c0 0 0 0 0 0 0.105 0.105 0.227 0.18 0.357 0.229 0.356 0.133 0.771 0.057 1.057-0.229l4.586-4.586c0.286-0.286 0.362-0.702 0.229-1.057-0.049-0.13-0.124-0.252-0.229-0.357z"/>
    265. </Viewbox>
    266. </Border>
    267. </Grid>
    268. </Grid>
    269. <Grid Grid.Row="1" Grid.Column="0">
    270. <Grid.ColumnDefinitions>
    271. <ColumnDefinition Width="120"/>
    272. <ColumnDefinition Width="*"/>
    273. </Grid.ColumnDefinitions>
    274. <Label Style="{DynamicResource LabelTagInfo}" Content="Suche in Genres:" Grid.Column="0" Foreground="{DynamicResource VordergrundfarbeBrush}" Margin="10, 0, 0, 0"/>
    275. <ComboBox Name="cmbGenre" Grid.Column="1" Margin="10, 4, 10, 4" ToolTip="Wähle hier aus, in welchen Genres gesucht werden soll..." IsEditable="False" ItemsSource="{Binding AnzuzeigendeGenres}">
    276. <ComboBox.ItemTemplate>
    277. <DataTemplate>
    278. <CheckBox Content="{Binding Genre, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsChecked="{Binding IstSelektiert, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Background="Transparent"/>
    279. </DataTemplate>
    280. </ComboBox.ItemTemplate>
    281. </ComboBox>
    282. </Grid>
    283. </Grid>
    284. <Grid Name="Deck1oder2" Grid.Column="1" Grid.Row="2">
    285. <Grid.RowDefinitions>
    286. <RowDefinition Height="50*"/>
    287. <RowDefinition Height="50*"/>
    288. </Grid.RowDefinitions>
    289. <RadioButton Name="rdbtnDeck1" Grid.Row="0" GroupName="ZurPlaylistZufuegen" Content="Plattendeck 1" ToolTip="Ausgewählte Musik zur Playlist von Deck 1 zufügen..." Margin="10, 10, 10, 10" Foreground="{DynamicResource VordergrundfarbeBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" IsChecked="True"/>
    290. <RadioButton GroupName="ZurPlaylistZufuegen" Content="Plattendeck 2" Grid.Row="1" ToolTip="Ausgewählte Musik zur Playlist von Deck 2 zufügen..." Margin="10, 10, 10, 10" Foreground="{DynamicResource VordergrundfarbeBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" IsChecked="{Binding Deck2IstSelektiert, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    291. </Grid>
    292. <!--<Grid Grid.Row="2" Grid.Column="1">
    293. <Grid.ColumnDefinitions>
    294. <ColumnDefinition Width="50*"/>
    295. <ColumnDefinition Width="50*"/>
    296. </Grid.ColumnDefinitions>
    297. <Label Style="{DynamicResource LabelTagInfo}" Content="Suchen in Genres:" Grid.Column="0" Foreground="{DynamicResource VordergrundfarbeBrush}" Margin="10, 10, 10, 0" ToolTip="Suchen in Genres..."/>
    298. <ComboBox Name="cmbGenre" Grid.Column="1" Margin="10" ToolTip="Wähle hier aus, in welchen Genres gesucht werden soll..." IsEditable="False" ItemsSource="{Binding AnzuzeigendeGenres}">
    299. <ComboBox.ItemTemplate>
    300. <DataTemplate>
    301. <CheckBox Content="{Binding Genre, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsChecked="{Binding Vorhanden, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    302. </DataTemplate>
    303. </ComboBox.ItemTemplate>
    304. </ComboBox>
    305. </Grid>-->
    306. <Grid Grid.Row="2" Grid.Column="2">
    307. <TextBlock Name="PlatzFuerWerbung" Text="Hier könnte deine Werbung stehen..." Foreground="{DynamicResource VordergrundfarbeBrush}" HorizontalAlignment="Center"/>
    308. </Grid>
    309. <Grid Name="AudioCDs" Grid.Column="3" Grid.Row="2">
    310. <Grid.RowDefinitions>
    311. <RowDefinition Height="50*"/>
    312. <RowDefinition Height="50*"/>
    313. </Grid.RowDefinitions>
    314. <Label Style="{DynamicResource LabelTagInfo}" Content="CD-Laufwerk:" Foreground="{DynamicResource VordergrundfarbeBrush}" Margin="10, 0, 0, 0" Grid.Row="0" HorizontalAlignment="Center"/>
    315. <Grid Grid.Row="1">
    316. <Grid.ColumnDefinitions>
    317. <ColumnDefinition Width="80*"/>
    318. <ColumnDefinition Width="10*"/>
    319. <ColumnDefinition Width="10*"/>
    320. </Grid.ColumnDefinitions>
    321. <ComboBox Grid.Column="0" Name="lstCDDrives" ToolTip="Wähle das angezeigte CD-Laufwerk aus..." IsEditable="False" ItemsSource="{Binding CDLaufwerke, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Margin="10, 4, 10, 4" SelectedIndex="{Binding CDDriveIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    322. <Border Name="brdRefreshCDDrives" Grid.Column="1" Style="{DynamicResource Navigationsbuttons}" ToolTip="Aktualisiere CD-Laufwerke..." Margin="20, 4, 20, 4">
    323. <Border.InputBindings>
    324. <MouseBinding MouseAction="LeftClick" Command="{Binding ErmittleCDLaufwerke}"/>
    325. </Border.InputBindings>
    326. <Viewbox Stretch="Uniform">
    327. <Path Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M27.802 5.197c-2.925-3.194-7.13-5.197-11.803-5.197-8.837 0-16 7.163-16 16h3c0-7.18 5.82-13 13-13 3.844 0 7.298 1.669 9.678 4.322l-4.678 4.678h11v-11l-4.198 4.197zM29 16c0 7.18-5.82 13-13 13-3.844 0-7.298-1.669-9.678-4.322l4.678-4.678h-11v11l4.197-4.197c2.925 3.194 7.13 5.197 11.803 5.197 8.837 0 16-7.163 16-16h-3z"/>
    328. </Viewbox>
    329. </Border>
    330. <Border Name="brdEjectCD" Grid.Column="2" Style="{DynamicResource Navigationsbuttons}" ToolTip="CD laden / auswerfen..." Margin="20, 4, 20, 4">
    331. <Border.InputBindings>
    332. <MouseBinding MouseAction="LeftClick" Command="{Binding WerfeCDAus}"/>
    333. </Border.InputBindings>
    334. <Viewbox Stretch="Uniform">
    335. <Path Stretch="Uniform" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M0 24h32v4h-32zM16 4l16 16h-32z"/>
    336. </Viewbox>
    337. </Border>
    338. </Grid>
    339. </Grid>
    340. </Grid>
    341. </UserControl>
    Man könnte was basteln, was einen Fehler wirft, wenn das LVM ein zweitesmal erzeugt wird:

    VB.NET-Quellcode

    1. Public Class LayerViewModel
    2. private shared InstanceExists As boolean = False
    3. Private Property Suche As ViewModel.SucheViewModel 'hier im LayerViewModel kann man beliebig viele verschiedene ViewModels anlegen, hier mal das Beispiel mit der Suche
    4. Sub New()
    5. Suche = New ViewModel.SucheViewModel(Me)
    6. if InstanceExists then stop
    7. InstanceExists = true
    8. End Sub
    9. Public ReadOnly Property SucheViewModel() As ViewModel.SucheViewModel
    10. Get
    11. Return Suche
    12. End Get
    13. End Property
    14. End Class

    kafffee schrieb:

    Klar. Was hast du vor nachzuschauen?


    Schauen wo denn der Fehler ist ;) Jedenfalls sehe ich ihn nicht. Ich würde fast wetten, das du das ViewModel nicht dem DataContext von X zuweist und deshalb keine Daten siehst.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D
    Kleiner Fortschritt beim Debuggen. Dank des Vorschlages von @ErfinderDesRades weiss ich jetzt: Aha, es gibt nur eine Instanz.

    Aber der DataContext ist korrekt gesetzt. Die anderen Daten, die nicht mit der Sub Initialisieren() zusammenhängen, werden angezeigt. Hab das mal probiert.

    Dann hab ich gedacht: Vielleicht das Threading. Weil das Problem hatte ich schon mal, da wurde trotz korrekten Bindings die View nicht aktualisiert, die Werte aber in der Debug-Ausgabe angezeigt.

    Also hab ich das hier versucht:

    VB.NET-Quellcode

    1. Dim LadeMusikBibliothekThread As New Thread(AddressOf MainModule.LayerVM.SucheViewModel.Initialisieren)
    2. LadeMusikBibliothekThread.IsBackground = True
    3. LadeMusikBibliothekThread.Start()


    VB.NET-Quellcode

    1. Public Sub Initialisieren()
    2. MainModule.MainDispatcher.Invoke(Sub () MusikdatenbankLaden_Execute(Nothing))
    3. MainModule.MainDispatcher.Invoke(Sub () GeneriereGenreListe())
    4. MainModule.MainDispatcher.Invoke(Sub () ErstelleDefault())
    5. End Sub


    Da werden auch keine Daten angezeigt.

    Also muss es ja denke ich an der Sub ErstelleDefault() liegen, denn MusikdatenbankLaden_Execute(Nothing) und GeneriereGenreListe() funktioniernen soweit auch, das hab ich getestet. Die Musikdatenbank wird geladen und die Genreliste wird auch angezeigt. Hier mal die Sub:

    VB.NET-Quellcode

    1. Public Sub ErstelleDefault()
    2. _AnzuzeigendeInterpreten = CollectionViewSource.GetDefaultView(MainModule.InhaltGesamt.OrderBy(Function(o) o.Interpret).GroupBy(Function(f) f.Interpret).Select(Function(g) g.First()))
    3. _AnzuzeigendeAlben = CollectionViewSource.GetDefaultView(MainModule.InhaltGesamt.OrderBy(Function(o) o.Album).GroupBy(Function(f) f.Album).Select(Function(g) g.First()))
    4. _AnzuzeigendeMusiktitel = CollectionViewSource.GetDefaultView(MainModule.InhaltGesamt.OrderBy(Function(o) o.Musiktitel).GroupBy(Function(f) f.Musiktitel).Select(Function(g) g.First()))
    5. _AnzuzeigendeRadiostreams = CollectionViewSource.GetDefaultView(MainModule.InhaltGesamt.OrderBy(Function(o) o.Album).GroupBy(Function(f) f.Album).Select(Function(g) g.First()))
    6. _AnzuzeigendeInterpreten.Filter = AddressOf AnzuzeigendeInterpreten_Filter
    7. _AnzuzeigendeAlben.Filter = AddressOf AnzuzeigendeAlben_Filter
    8. _AnzuzeigendeMusiktitel.Filter = AddressOf AnzuzeigendeMusiktitel_Filter
    9. _AnzuzeigendeRadiostreams.Filter = AddressOf AnzuzeigendeRadiostreams_Filter
    10. _AnzuzeigendeInterpreten.SortDescriptions.Add(New SortDescription(NameOf(ViewModel.MP3FileInfoVM.Interpret), ListSortDirection.Ascending))
    11. _AnzuzeigendeAlben.SortDescriptions.Add(New SortDescription(NameOf(ViewModel.MP3FileInfoVM.Album), ListSortDirection.Ascending))
    12. _AnzuzeigendeMusiktitel.SortDescriptions.Add(New SortDescription(NameOf(ViewModel.MP3FileInfoVM.Musiktitel), ListSortDirection.Ascending))
    13. _AnzuzeigendeRadiostreams.SortDescriptions.Add(New SortDescription(NameOf(ViewModel.MP3FileInfoVM.Album), ListSortDirection.Ascending))
    14. MarkierterInterpret = -1
    15. MarkiertesAlbum = -1
    16. MarkierterMusiktitel = -1
    17. MarkierterRadiostream = -1
    18. End Sub


    Also: Kann es sein, dass die zu einem bestimmten Zeitpunkt aufgerufen werden muss, weil wenn ich sie ja über die Sub New() von meinem SucheViewModel aufrufe, dann funktioniert sie ja...
    Also wenn du das ViewModel in einem NebenThread initialisierst - da würde ich auch allerlei Fehlverhalten erwarten.
    Bei verschiedenen Threads funktioniert auch mein Versuch mit der Shared-Variable nicht, weil ein Thread erstellt seine Variablen selber - auch die Shareds.
    Da müsste man dann mit VolatileRead/VolatileWrite ran, um auch threadübergreifende Einzigartigkeit verifizieren zu können.

    ErfinderDesRades schrieb:

    Also wenn du das ViewModel in einem NebenThread initialisierst - da würde ich auch allerlei Fehlverhalten erwarten.


    Auch wenn ich das nicht tue: Nur eine Instanz.

    Aber meine OC InhaltGesamt wird in einer Funktion befüllt, die mit .IsBackground = True aufgerufen wird.

    Das Komische ist: Meine Genres werden angezeigt, obwohl diese Werte auch von InhaltGesamt stammen...

    Und: Wenn ich einen Haltepunkt in der ErstelleDfault() setze,dann sind meine _AnzuzeigendeInterpreten z.B. korrekt befüllt...