Связывание WPF ComboBox не работает должным образом - PullRequest
4 голосов
/ 27 октября 2008

Я хочу, чтобы свойство ItemsSource моего WPF ComboBox было связано со свойством MyListObject MyList. Проблема в том, что когда я обновляю свойство MyList в коде, WPF ComboBox не отражает обновление. Я поднимаю событие 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

Спасибо!

Ответы [ 3 ]

3 голосов
/ 27 октября 2008

Вы привязываетесь к списку строк. Этот класс списка не реализует свойство Inotify. Вместо этого вы должны использовать наблюдаемую коллекцию. Я также заметил в вашем коде позади вас объявить

Private obj As New MyListObject

Это не статический ресурс, к которому вы привязали поле со списком. Таким образом, ваш дополнительный вызов не будет отражен в вашем представлении.

2 голосов
/ 27 октября 2008

ObservableCollection, скорее всего, является решением, но если оно все еще дает вам горе, вы можете напрямую получить доступ к своему статическому ресурсу, вызвав следующий код после обновления списка:

DirectCast(Me.FindResource("MyListObject"), ObjectDataProvider).Source = _myList
0 голосов
/ 27 октября 2008

Попробуйте использовать BindingList (Of T) вместо List (Of T).

Редактировать: я новичок в WPF, и похоже, что BindingList не является полным решением вашей проблемы, но это может быть шагом в правильном направлении. Мне удалось протестировать MyListObject, преобразованный в BindingList в WinForm, и событие ListChanged было вызвано в ComboBox, который затем обновил свой список.

Я нашел это (возможное) решение, чтобы обернуть ваш класс в коллекцию 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...