1

For example, I have a ItemsControl with a custom DataTemplate:

<ItemsControl Name="CategoriesList">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

For example my collection contains 100 elements. I want to get which CheckBoxes is checked and which is not or I just want to change a Content property. In both cases I need to get a CheckBox element from code. So it's easy to get Items from code:

var cList = CategoriesList.Items;
foreach (var item in cList)
{
    //Do Something
}

But I need to get CheckBoxes from these items. Is it possible?

Thank you!

Sachin
  • 40,216
  • 7
  • 90
  • 102
splash27
  • 2,057
  • 6
  • 26
  • 49
  • You can use the solution from Aman Khandelwal but I think it's unnecessarily complicated. It is easier to extend the object in the collection by property type bool MyIsChecked and the bind the checkbox IsChecked property.`` – Jan Smuda Feb 26 '14 at 11:49

1 Answers1

2

You need to use a visual tree helper for the same

I have tried it with a listbox and it works! Ant I think the same would work for an ItemsControl as well because the properties and methods of a listbox and an ItemsControl are same.

Just make and use this Method to dig inside the visual tree of a listbox

 public static T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
        {
            try
            {
                int childCount = VisualTreeHelper.GetChildrenCount(parentElement);
                if (childCount == 0)
                    return null;

                for (int i = 0; i < childCount; i++)
                {
                    var child = VisualTreeHelper.GetChild(parentElement, i);
                    if (child != null && child is T)
                    {
                        return (T)child;
                    }
                    else
                    {
                        var result = FindFirstElementInVisualTree<T>(child);
                        if (result != null)
                            return result;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return null;
        }

And that's how you are going to use this method in code

                ListBoxItem SelectedListBoxItem = this.lstInstagramTags.ItemContainerGenerator.ContainerFromIndex(int index) as ListBoxItem;
                if (SelectedListBoxItem == null)
                    return;
                // Iterate whole listbox tree and search for this items
                Button btn= FindFirstElementInVisualTree<Button>(SelectedListBoxItem );
                btn.Content="Hello";

And a Link too

Hope this helps.

Community
  • 1
  • 1
A.K.
  • 3,321
  • 1
  • 15
  • 27
  • I changed my ItemsControl to ListBox, because it doesn't matter to me. But the method doesn't work. It returns "Reference is a not a valid visual DependencyObject" – splash27 Feb 26 '14 at 11:46
  • Sorry, already fixed. =) Thank you very much! This is what I really need, because it able to fix many problems in my app. =) – splash27 Feb 26 '14 at 11:49
  • strange behaviour found. If index in `ContainerFromIndex` is larger than 19, it returns "Reference is a not a valid visual DependencyObject". Actually my ListBox include 74 items. What's the problem? – splash27 Feb 26 '14 at 12:40
  • Actually it is connected with the fact, that ContainerFromIndex returns null at indexes larger than 19 (at least in my case). I don't know why. – splash27 Feb 26 '14 at 12:57
  • try putting it inside Dispatcher.BeginInvoke method. That could solve the issue. Though I am not sure on this. – A.K. Feb 26 '14 at 13:04