tags:

views:

62

answers:

2

Hi there,

Is there an event handler that will be called when an item is added in a listbox in WPF?

Thanks!

+2  A: 

Take a different approach. Create an ObservableCollection (which does have such an event) and set the ItemsSource of the ListBox to this collection. In other words, in WPF you should think about the problem differently. The control isn't necessarily what is being modified ... the collection behind it is.

UPDATE
Based on your comment to Mitch's answer which indicates your binding source is actually an XML document, I suggest looking into hooking up to the XObject.Changed event of the XML document/element/etc. This will give you change information about the XML structure itself - not the ItemCollection which is an implementation detail you shouldn't need to consider. For example, ItemCollection (or any INotifyCollectionChanged) doesn't guarantee an individual event for every change. As you noted, sometimes you'll just get a generic reset notification.

Josh Einstein
+1 from me. ...
Mitch Wheat
Hi Josh, here's my code.XmlDocument doc = new XmlDocument();// Initially value "<ParentNode></ParentNode>"doc = mngr.XmlDoc;XmlDataProvider xmlDP = new XmlDataProvider();xmlDP.Document = doc;xmlDP.XPath = "/ParentNode/ChildNode";CollectionViewSource collection = new CollectionViewSource();collection.Source = xmlDP;collection.SortDescriptions.Add(new SortDescription("ChildNodeName", ListSortDirection.Ascending);Binding bnd = new Binding();bnd.Source = collection;listbox.SetBinding(ListBox.ItemsSourceProperty, bnd);Sample Xml Document:<ParentNode></ParentNode>
apoc29
+2  A: 

The problem is that the INotifyCollectionChanged interface which contains the event handler is explicitly implemented, which means you have to first cast the ItemCollection before the event handler can be used:

public MyWindow()   
{   
    InitializeComponent();   

    ((INotifyCollectionChanged)mListBox.Items).CollectionChanged +=   
        mListBox_CollectionChanged;   
}   

private void mListBox_CollectionChanged(object sender,    
    NotifyCollectionChangedEventArgs e)   
{   
    if (e.Action == NotifyCollectionChangedAction.Add)   
    {   
        // scroll the new item into view   
        mListBox.ScrollIntoView(e.NewItems[0]);   
    }       
}

Ref.

Josh's advice about the observable collection should also be considered.

Mitch Wheat
Thanks Mitch! It worked! However, I encountered this weird bug. The listbox is binded to a CollectionViewSource where the source is a XMLDocument. I specified XPath as .XPath = "/RootNode/ChildNode". The weird bug is that "sometimes" when I launch my application, display the listbox, it contains an item (SHOULD not) and when I checked the ListBoxItem, the item is in XMLDocument having in it "<RootNode></RootNode>" This is occurs say 2/5 times. I posted the previous question so that I will know when an item is aded but whn ths weird behvior hapen, I receiv a NotifyCollectionChangedAction.Reset
apoc29
Hard to say without seeing the code that populates the XML doc. Maybe it has to do with async loading. But I still believe you are fighting against a model WPF is trying to guide you into by digging into the internals of ItemCollection. You really should never even have to think about ItemCollection or ListBoxItem unless you are writing a control.
Josh Einstein