6
votes

This is my first post here so I hope you could help me with my problem regarding WPF.

I have a listbox that is bind with an ObservableCollection:

    public ObservableCollection<DeviceSetting> DeviceSettings
                {
                    get { return _deviceSettings; }
                    set { _deviceSettings = value; }
                }

   <ListBox ItemTemplate="{StaticResource IPItemTemplate}" Name="listBoxAddresses" SelectionMode="Extended" ItemsSource="{Binding Path=TestSetting.DeviceSettings, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
     ItemContainerStyle="{StaticResource ContainerStyle}" />

The situation here is, I would like to know if a new item has been added to the list so what I did was create a CollectionChanged event:

TestSetting.DeviceSettings.CollectionChanged += mListBox_CollectionChanged;  

private void mListBox_CollectionChanged(object sender,NotifyCollectionChangedEventArgs e)
{
   if (e.Action == NotifyCollectionChangedAction.Add)
   {
       for (int i = 0; i < TestSetting.DeviceSettings.Count; i++){

       ListBoxItem myListBoxItem = (ListBoxItem)(listBoxAddresses.ItemContainerGenerator.ContainerFromItem(listBoxAddresses.Items[i]));


        if (!TestSetting.DeviceSettings[i].IsNetwork && DeviceDiscovery.IsSelected)
                  myListBoxItem.IsEnabled = false;

        else if (TestSetting.DeviceSettings[i].IsNetwork && !DeviceDiscovery.IsSelected)
                  myListBoxItem.IsEnabled = false;
        else
                  myListBoxItem.IsEnabled = true;

     }
 }

But a problem occurs at this statement:

ListBoxItem myListBoxItem = (ListBoxItem)(listBoxAddresses.ItemContainerGenerator.ContainerFromItem(listBoxAddresses.Items[i]));

Everytime I added a new item, the statement above always returns null so the new item that was added was not checked if would be enabled or not. Is there a way for this statement to return the correct ListBoxItem that I need?

3
Why just not use bindings inside ItemTemplate (with a help of some Converter)? You`re checking properies anyway, you only do this manually right now.icebat

3 Answers

8
votes

You're handling the underlying collections CollectionChanged event. Just because the collection was changed does not mean that the item has been rendered and the UIElement is ready.

Register for the ItemsGenerator.StatusChanged event which should guarantee that the UIElement is ready.

0
votes

I didn't find the ItemsGenerator.StatusChanged event in Windows Phone, but it worked with listBoxAddresses.LayoutUpdated

I also had to make sure myListBoxItem was different from null.

0
votes

In case you're loading the control and trying to access...

ItemContainerGenerator.ContainerFromItem(object here)

I was able to work around the issue by doing it in my ListBox.Loaded event. For example

SourceColumnListBox.Loaded += SourceColumnListBox_Loaded;

Then inside the SourceColumnListBox_Loaded handler, things worked fine.