2008-10-27 2 views
4

Я хочу, чтобы свойство ItemsSource WPF ComboBox привязывалось к свойству MyList MyListObject. Проблема в том, что когда я обновляю свойство MyList в коде, WPF ComboBox не отражает обновление. Я поднимаю событие PropertyChanged после выполнения обновления, и я думал, что WPF должен автоматически реагировать, обновляя интерфейс. Я что-то упускаю?Связывание WPF ComboBox не работает должным образом

Вот объект 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

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

Private obj As New MyListObject 

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

+1

Это Безразлично» t, что изменение свойства на ObservableCollection оказывает какое-либо влияние на обновление источника items combobox. – 2008-10-27 19:02:56

0

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

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

Я нашел это (возможно) решение, чтобы обернуть ваш класс в ObservableCollection, которые могут помочь вам решить вашу проблему

Enabling WPF Magic Using WCF - Part 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 
+0

Список привязок не реализует INotifyCollectionChanged или INotifyPropertyChanged, что и ищет wpf. – 2008-10-27 18:46:28

+0

BindingList поддерживает «старое» уведомление об изменении, которое WPF по-прежнему уважает. Кроме того, BindingList активирует измененное уведомление при изменении любого из дочерних объектов (в отличие от ObservableCollection). Кроме того, BindingList - это IList, который хорош, потому что у него есть возможность LINQ, такая как .ForEach. – 2010-04-28 16:23:47

2

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

DirectCast(Me.FindResource("MyListObject"), ObjectDataProvider).Source = _myList