Привязка WPF ComboBox работает не так, как ожидалось
-
04-07-2019 - |
Вопрос
Я хочу, чтобы свойство ItemsSource моего WPF ComboBox ComboBox было привязано к свойству MyListObject myList.Проблема в том, что когда я обновляю свойство myList в коде, поле со списком WPF не отражает обновление.Я вызываю событие PropertyChanged после выполнения обновления, и я думал, что WPF должен был автоматически реагировать, обновляя пользовательский интерфейс.Я что-то упускаю?
Вот объект CLR:
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
Вот 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>
И вот простой код, лежащий в основе:
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
Спасибо!
Решение
Вы привязываетесь к списку строк.Этот класс list не реализует свойство Inotifyproperty .Вместо этого вам следует использовать observablecollection .Я также замечаю в вашем коде за вами объявление
Private obj As New MyListObject
Это не тот статический ресурс, к которому вы привязали поле со списком.Таким образом, ваш вызов add не будет отражен в вашем представлении.
Другие советы
ObservableCollection, скорее всего, является решением, но если это все еще доставляет вам неудобства, вы можете напрямую получить доступ к своему статическому ресурсу, вызвав следующий код после обновления вашего списка:
DirectCast(Me.FindResource("MyListObject"), ObjectDataProvider).Source = _myList
Попробуйте использовать Список привязок (Из T) вместо Списка (Из T).
Редактировать:Я новичок в WPF, и похоже, что BindingList не является полным решением вашей проблемы, но это может быть шагом в правильном направлении.Мне удалось протестировать MyListObject, преобразованный в BindingList в WinForm, и событие ListChanged было вызвано в поле со списком, которое затем обновило свой список.
Я нашел это (возможное) решение обернуть ваш класс в ObservableCollection, которое может помочь вам решить вашу проблему
Включение WPF Magic с помощью WCF - Часть 1
Это код для обновления вашего объекта до BindingList .Объедините свой код с кодом с этого ресурса, и все будет готово.
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