WPF ComboBox-Bindung nicht wie erwartet funktioniert
-
04-07-2019 - |
Frage
Ich möchte, dass meine WPF-ComboBox die ItemsSource-Eigenschaft gebunden werden MyListObject s MyList Eigentum.Das problem ist, dass wenn ich ein update der MyList-Eigenschaft im code, die WPF-ComboBox nicht widerspiegelt das update.Ich Hebe das PropertyChanged-Ereignis, nachdem ich das update ausführen, und ich dachte, WPF sollte automatisch Antworten, indem Aktualisierung der Benutzeroberfläche.Bin ich etwas fehlt?
Hier ist das CLR-Objekt:
Imports System.ComponentModel
Public Class MyListObject
Implements INotifyPropertyChanged
Private _mylist As New List(Of String)
Public Sub New()
_mylist.Add("Joe")
_mylist.Add("Steve")
End Sub
Public Property MyList() As List(Of String)
Get
Return _mylist
End Get
Set(ByVal value As List(Of String))
_mylist = value
End Set
End Property
Public Sub AddName(ByVal name As String)
_mylist.Add(name)
NotifyPropertyChanged("MyList")
End Sub
Private Sub NotifyPropertyChanged(ByVal info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub
Public Event PropertyChanged(ByVal sender As Object, _
ByVal e As System.ComponentModel.PropertyChangedEventArgs) _
Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
Hier ist die XAML:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
xmlns:local="clr-namespace:WpfApplication1"
>
<Window.Resources>
<ObjectDataProvider x:Key="MyListObject" ObjectType="{x:Type local:MyListObject}"/>
</Window.Resources>
<Grid>
<ComboBox Height="23"
Margin="24,91,53,0"
Name="ComboBox1"
VerticalAlignment="Top"
ItemsSource="{Binding Path=MyList, Source={StaticResource MyListObject}}"
/>
<TextBox Height="23"
Margin="24,43,134,0"
Name="TextBox1"
VerticalAlignment="Top" />
<Button Height="23"
HorizontalAlignment="Right"
Margin="0,43,53,0"
Name="btn_AddName"
VerticalAlignment="Top"
Width="75">Add</Button>
</Grid>
</Window>
Und hier ist der einfache code-behind:
Class Window1
Private obj As New MyListObject
Private Sub btn_AddName_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) _
Handles btn_AddName.Click
obj.AddName(TextBox1.Text)
End Sub
End Class
Vielen Dank!
Lösung
Sie sind die Bindung an eine Liste von Strings. Diese Liste Klasse nicht implementiert Inotifyproperty. Sie sollten stattdessen eine ObservableCollection verwenden. Ich habe auch in Ihrem Code bemerken hinter Ihnen erklären
Private obj As New MyListObject
Dies ist nicht die statische Ressource Sie das Kombinationsfeld zu begrenzen. So würde Ihr Add Anruf nicht aus Ihrer Sicht reflektiert werden.
Andere Tipps
Die ObservableCollection ist höchstwahrscheinlich die Lösung, aber wenn es immer noch gibt Ihnen Kummer, können Sie direkt Ihre statische Ressource zugreifen, indem Sie den folgenden Code aufrufen, nachdem die Liste aktualisiert wird:
DirectCast(Me.FindResource("MyListObject"), ObjectDataProvider).Source = _myList
Versuchen Sie es mit einem BindingList(Of T) anstatt eine Liste(Of T).
Edit:Ich bin neu in WPF und es sieht aus wie BindingList nicht eine komplette Lösung für Ihr problem, aber es könnte ein Schritt in die richtige Richtung.Ich war in der Lage zu test die MyListObject konvertiert BindingList in WinForm und das ListChanged-Ereignis wurde ausgelöst, um die ComboBox, die dann aktualisiert die Liste.
Ich fand dieses (mögliche) Lösung zu wickeln Sie Ihre Klasse in eine ObservableCollection, die helfen könnten, Ihr problem zu lösen
Aktivieren von WPF-Magie Mithilfe von WCF - Teil 1
Dies ist der code, um zu aktualisieren Sie Ihr Objekt an eine BindingList.Kombinieren Sie Ihren code mit dem code aus, dass die Ressource, und Sie sollten gut sein zu gehen.
Public Class MyListObject
...
'Private _mylist As New List(Of String)
Private _mylist As New BindingList(Of String)
...
'Public Property MyList() As List(Of String)
' Get
' Return _mylist
' End Get
' Set(ByVal value As List(Of String))
' _mylist = value
' End Set
'End Property
Public Property MyList() As BindingList(Of String)
Get
Return _mylist
End Get
Set(ByVal value As BindingList(Of String))
_mylist = value
End Set
End Property
...
End Class