Sorry if this is a duplicate question. There are quite a few questions around this topic, but I can't seem to get it figured out. I'm trying to bind a listbox to an ObservableCollection and keep the listbox updated when items are added to the collection.
I have a class called CollectionOfBlogs:
Public Class CollectionOfBlogs
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Public Sub New(ByVal name As String)
Me.FullName = name
End Sub
Private _FullName As String
Public Property FullName() As String
Get
Return _FullName
End Get
Set(ByVal value As String)
_FullName = value
NotifyPropertyChanged("FullName")
End Set
End Property
Public Sub NotifyPropertyChanged(ByVal propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Then another class where I setup the ObservableCollection of CollectionOfBlogs (above) and a sub to add items to the collection:
Public Class ITRSBlogs
Public blogNamesList As New ObservableCollection(Of CollectionOfBlogs)
Public Sub addBlog(ByVal FullName as String)
blogNamesList.Add(New CollectionOfBlogs(FullName))
End Sub
End Class
I bind the listbox to the blogNamesList collection in the ITRSBlogs Class (above) from my main page loaded event:
Dim blogClass As New ITRSBlogs
Me.BloggingMenuListBox.ItemsSource = blogClass.blogNamesList
Here is the XAML of my listbox. It's bound in the codebehind, not in the XAML (just thought I should mention that).
<ListBox Name="BloggingMenuListBox"/>
Before binding the collection to the listbox, I load the collection with items from the database, and they show up in the listbox just fine. These 2 subs below are actually in the ITRSBlogs Class as well, and I call FillBlogLists from my pages loaded event.
Public Sub FillBlogLists()
Dim query = theContext.GetBlogsOrderedByNameQuery
theContext.Load(query, AddressOf OnBlogsLoaded, Nothing)
End Sub
Private Sub OnBlogsLoaded(ByVal lo As LoadOperation(Of Blog))
blogList.Clear()
For Each s In lo.AllEntities
blogList.Add(CType(s, Blog))
Next
For Each item In blogList
blogNamesList.Add(New CollectionOfBlogs(item.FullName))
Next
End Sub
Beyond this, I have a simple textbox and button on a page. When a name is entered into the textbox, and the button is clicked, I call the addBlog(passing in name from textbox) sub routine in the ITRSBlogs Class (back up the page a bit) to add the item to the collection.
Problem is, when I add an item to the collection, the listbox is not updated. I'm new to Observable Collections (and many other things : ), so maybe I'm just really off here. Can anyone tell me what I'm doing wrong?
The code you posted looks fine to me. I replicated your code (in C#, but I tried to keep it as close to your code as possible) and it just worked. The only code you didn't post is the event handler of the Add
button. Did you check that it is actually called and that a new item is added to the collection?
Anyway here is my code, maybe you can spot where the difference is between this and your version:
CollectionOfBlogs.cs:
public class CollectionOfBlogs : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _FullName;
public string FullName
{
get
{
return this._FullName;
}
set
{
if (this._FullName != value)
{
this._FullName = value;
this.OnPropertyChanged("FullName");
}
}
}
public CollectionOfBlogs(string name)
{
this._FullName = name;
}
public virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public override string ToString()
{
return this._FullName;
}
}
ITRSBlogs.cs:
public class ITRSBlogs
{
public ObservableCollection<CollectionOfBlogs> blogNamesList = new ObservableCollection<CollectionOfBlogs>();
public void AddBlog(string fullName)
{
this.blogNamesList.Add(new CollectionOfBlogs(fullName));
}
public void FillBlogList()
{
this.blogNamesList.Clear();
this.AddBlog("First blog");
this.AddBlog("Another blog");
}
}
MainWindow.xaml:
<Window x:Class="ObservableRefreshDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
<ListBox Name="BloggingMenuListBox"/>
<Button Content="Add" Height="23" HorizontalAlignment="Left" Margin="154,276,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="12,276,0,0" Name="txtName" VerticalAlignment="Top" Width="120" />
</Grid>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private ITRSBlogs blogClass = new ITRSBlogs();
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.blogClass.FillBlogList();
this.BloggingMenuListBox.ItemsSource = this.blogClass.blogNamesList;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.blogClass.AddBlog(this.txtName.Text);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.