Benutzer mit den meisten Antworten
ComboBox Datenbindung innerhalb einer ListView

Frage
-
Guten Tag
In einer ListView, welche die Daten per Bindung von einer Klasse erhält, habe ich einen TextBlock, einen ToggleSwitch und eine ComboBox. Die Bindung an den TextBlock und den ToggleSwitch funktioniert einwandfrei (TwoWay Binding). Leider klappt das Binding für die ComboBox nicht. Die Elemente habe ich mithilfe von ComboBoxItem direkt in XAML definiert, die Bindung, welches Item angewählt ist, soll daher auch im TwoWay Mode stattfinden. Wie bewerkstellige ich das genau?
Mit freundlichen Grüssen
Antworten
-
Hallo Andy,
in XAML ist es so das das ausgewählte Element immer dem entspricht was auch angezeigt wird. Das heißt das eine ComboBox mit ComboBoxItems aus wirklich entsprechende Items in SelectedItem zurück gibt. Eine per Datenbindung gefüllte ComboBox dagegen kann auch Strings ausgewählt haben, sofern die übergebene Liste welche enthält.
Daher musst du entweder SelectedIndex binden und darüber bestimmen was ausgewählt wurde oder aber du befüllst die ComboBox doch wieder per ItemsSource und kannst direkt das ausgewählte Item binden.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert andy-dev Samstag, 8. August 2015 18:18
-
Hi,
das funktioniert schon richtig. Du musst aber berücksichtigen, dass Du im Falle von ComboBoxItems im XAML mit gebundenen SelectedIndex arbeiten solltest. Wenn Du mit SelectedItem arbeiten willst, dann muss die gebundene Eigenschaft vom Typ ComboBoxItem sein. In diesem Fall hast Du dann etwas mehr Aufwand für eine Konvertierung. Besser ist es deshalb mit einer Liste vom Ojekten zu arbeiten, die als ItemsSource an die Combobox gebunden werden.Hier mal meine Demo:
XAML:
<ListView DataContext="{Binding Source={StaticResource vm}}" ItemsSource="{Binding View}"> <ListView.ItemTemplate> <DataTemplate> <Border BorderBrush="Red" BorderThickness="2"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{Binding AnzeigeText}" /> <ToggleSwitch Grid.Row="1" IsOn="{Binding Toggle}" /> <ComboBox Grid.Row="2" SelectedItem="{Binding CbItem, Mode=TwoWay}"> <ComboBox.Items> <ComboBoxItem Content="Item1"/> <ComboBoxItem Content="Item2"/> <ComboBoxItem Content="Item3"/> </ComboBox.Items> </ComboBox> <TextBox Grid.Row="3" Text="{Binding CbItemIndex, Mode=TwoWay}"/> </Grid> </Border> </DataTemplate> </ListView.ItemTemplate> </ListView>
Dazu der ViewModel:
Public Class Page02VM Private liste As ObservableCollection(Of Page02Data) Private cvs As CollectionViewSource Public ReadOnly Property View As ICollectionView Get If liste Is Nothing Then liste = New ObservableCollection(Of Page02Data) DatenLaden(liste) cvs = New CollectionViewSource() With {.Source = liste} End If Return cvs.View End Get End Property Private Sub DatenLaden(liste As ObservableCollection(Of Page02Data)) Dim rnd As New Random For i = 1 To 10 liste.Add(New Page02Data With { .AnzeigeText = String.Format("Zeile 1 {0}Text {1}", vbNewLine, i), .Toggle = rnd.NextDouble > 0.5, .CbItemIndex = rnd.Next(3)}) Next End Sub End Class Public Class Page02Data Implements INotifyPropertyChanged Public Property AnzeigeText As String Public Property Toggle As Boolean Private _cbItemIndex As Integer Public Property CbItemIndex As Integer Get Return Me._cbItemIndex End Get Set(value As Integer) If Me._cbItemIndex <> value Then Me._cbItemIndex = value OnPropertyChanged() End If End Set End Property Private _cbItem As ComboBoxItem Public Property CbItem As ComboBoxItem Get Return Me._cbItem End Get Set(value As ComboBoxItem) Me._cbItem = value End Set End Property #Region " OnPropertyChanged" Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private Sub OnPropertyChanged(<CallerMemberName> Optional propName As String = "") RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName)) End Sub #End Region End Class
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks- Als Antwort markiert andy-dev Samstag, 8. August 2015 18:18
-
Hi,
wie Tom Dir schon geraten hat, kann ich Dir auch nur raten, auf ComboBoxItems im XAML zu verzichten und eine Liste mit Objekten zu binden. Dann bekommst Du als SelectedItem das gewünschte ausgewählte Objekt und kannst ohne großen Aufwand auf die Innereien zugreifen.--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks- Als Antwort markiert andy-dev Samstag, 8. August 2015 20:29
Alle Antworten
-
Hallo Andy,
in XAML ist es so das das ausgewählte Element immer dem entspricht was auch angezeigt wird. Das heißt das eine ComboBox mit ComboBoxItems aus wirklich entsprechende Items in SelectedItem zurück gibt. Eine per Datenbindung gefüllte ComboBox dagegen kann auch Strings ausgewählt haben, sofern die übergebene Liste welche enthält.
Daher musst du entweder SelectedIndex binden und darüber bestimmen was ausgewählt wurde oder aber du befüllst die ComboBox doch wieder per ItemsSource und kannst direkt das ausgewählte Item binden.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert andy-dev Samstag, 8. August 2015 18:18
-
Vielen Dank für die schnelle Antwort. Leider muss ich in die jeweilige Comboboxen der ListView immer die selben Items zur Auswahl haben, deshalb habe ich diese per XAML als ComboBoxItems fix definiert. Das ausgewählte Item des jeweiligen ListViewItem muss ich allerdings binden können, leider will das überhaupt nicht funktionieren. Ev habe ich deine Antwort aber auch nicht ganz richtig verstanden.
Mit freundlichen Grüssen
-
Wo ist das Problem? Die ComboBox kannst du trotzdem per Datenbindung befüllen sofern du eine entsprechende Liste ins ViewModel/DataContext packst.
Sonst gilt weiterhin das du entweder das ComboBoxItem, das Datengebundene Element einer Datengebundenen ComboBox oder aber den Index auslesen kannst.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Hi,
das funktioniert schon richtig. Du musst aber berücksichtigen, dass Du im Falle von ComboBoxItems im XAML mit gebundenen SelectedIndex arbeiten solltest. Wenn Du mit SelectedItem arbeiten willst, dann muss die gebundene Eigenschaft vom Typ ComboBoxItem sein. In diesem Fall hast Du dann etwas mehr Aufwand für eine Konvertierung. Besser ist es deshalb mit einer Liste vom Ojekten zu arbeiten, die als ItemsSource an die Combobox gebunden werden.Hier mal meine Demo:
XAML:
<ListView DataContext="{Binding Source={StaticResource vm}}" ItemsSource="{Binding View}"> <ListView.ItemTemplate> <DataTemplate> <Border BorderBrush="Red" BorderThickness="2"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{Binding AnzeigeText}" /> <ToggleSwitch Grid.Row="1" IsOn="{Binding Toggle}" /> <ComboBox Grid.Row="2" SelectedItem="{Binding CbItem, Mode=TwoWay}"> <ComboBox.Items> <ComboBoxItem Content="Item1"/> <ComboBoxItem Content="Item2"/> <ComboBoxItem Content="Item3"/> </ComboBox.Items> </ComboBox> <TextBox Grid.Row="3" Text="{Binding CbItemIndex, Mode=TwoWay}"/> </Grid> </Border> </DataTemplate> </ListView.ItemTemplate> </ListView>
Dazu der ViewModel:
Public Class Page02VM Private liste As ObservableCollection(Of Page02Data) Private cvs As CollectionViewSource Public ReadOnly Property View As ICollectionView Get If liste Is Nothing Then liste = New ObservableCollection(Of Page02Data) DatenLaden(liste) cvs = New CollectionViewSource() With {.Source = liste} End If Return cvs.View End Get End Property Private Sub DatenLaden(liste As ObservableCollection(Of Page02Data)) Dim rnd As New Random For i = 1 To 10 liste.Add(New Page02Data With { .AnzeigeText = String.Format("Zeile 1 {0}Text {1}", vbNewLine, i), .Toggle = rnd.NextDouble > 0.5, .CbItemIndex = rnd.Next(3)}) Next End Sub End Class Public Class Page02Data Implements INotifyPropertyChanged Public Property AnzeigeText As String Public Property Toggle As Boolean Private _cbItemIndex As Integer Public Property CbItemIndex As Integer Get Return Me._cbItemIndex End Get Set(value As Integer) If Me._cbItemIndex <> value Then Me._cbItemIndex = value OnPropertyChanged() End If End Set End Property Private _cbItem As ComboBoxItem Public Property CbItem As ComboBoxItem Get Return Me._cbItem End Get Set(value As ComboBoxItem) Me._cbItem = value End Set End Property #Region " OnPropertyChanged" Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Private Sub OnPropertyChanged(<CallerMemberName> Optional propName As String = "") RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName)) End Sub #End Region End Class
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks- Als Antwort markiert andy-dev Samstag, 8. August 2015 18:18
-
Vielen Dank für die Hilfe hat nun Problemlos geklappt. Das Problem lag daran, dass ich erst nicht ganz verstanden habe, was es mit SelectedIndex auf sich hat, bzw. bis ich dann gemerkt habe, dass eben jeweils dieser zurückgegeben wird, wenn man die ComboBoxItems in XAML definiert. Nun habe ich die Datenbindung an SelectedIndex und prüfe jeweils, um welches Item es sich handelt. Vielen Dank!
Mit freundlichen Grüssen
-
Hi,
wie Tom Dir schon geraten hat, kann ich Dir auch nur raten, auf ComboBoxItems im XAML zu verzichten und eine Liste mit Objekten zu binden. Dann bekommst Du als SelectedItem das gewünschte ausgewählte Objekt und kannst ohne großen Aufwand auf die Innereien zugreifen.--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks- Als Antwort markiert andy-dev Samstag, 8. August 2015 20:29