Search code examples
c#.netwpfxamlitemscontrol

ItemControl: Change Property Of Control in ItemControl Based On "Content" of Control


I have the following code.

In my Example I have Displaying Buttons using ItemControl. Now i need to access particular button based on its content and change its property.

say,, i nee to change Background property of first button when ChangeBackGround button being Clicked. [See Screen shot at very below at my Question]

Have a look at below code and Screen Shot :

XAML:

<Window x:Class="ItemControlProblem.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">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50*" />
            <RowDefinition Height="261*" />
        </Grid.RowDefinitions>
        <ItemsControl Name="itemControlProblem" ItemsSource="{Binding Path=DataCollection}" Grid.RowSpan="2">
            <ItemsControl.Template>
                <ControlTemplate TargetType="ItemsControl">
                    <Border>
                        <StackPanel>
                            <ItemsPresenter></ItemsPresenter>
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </ItemsControl.Template>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"></StackPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding Path=DataToPresent}"></Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button Content="ChangeBackGround" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="215,104,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    </Grid>
</Window>

CODE BEHIND:

public partial class MainWindow : Window
    {
        private ObservableCollection<Data> dataCollection ;

        public MainWindow()
        {
            InitializeComponent();
            dataCollection = new ObservableCollection<Data>();

            dataCollection.Add(new Data("first"));
            dataCollection.Add(new Data("second"));
            dataCollection.Add(new Data("third"));
            dataCollection.Add(new Data("forth"));
            this.DataContext = this;
        }

        public ObservableCollection<Data> DataCollection
        {
            get
            {
                return this.dataCollection;
            }
            set
            {
                this.dataCollection = value;
            }
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            //I need to change Background of Perticular Button
            //Based On Content of Button [Here that is "first", "second", "third", "forth"]

            //How to change the color of perticular button based on Content of Button?
        }
    }

    public class Data 
    {
        private string dataToPresent;

        public Data()
        {

        }
        public Data(string dataArg)
        {
            this.dataToPresent = dataArg;
        }
        public string DataToPresent 
        {
            get
            {
                return this.dataToPresent;
            }
            set
            {
                this.dataToPresent = value;
            }
        }
    }

Screen Shot:

enter image description here


Solution

  • Use this method to find visual children:

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }
    
                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }
    

    Example:

    var buttonFirst = FindVisualChildren<Button>(itemControlProblem)
        .Single(b => b.Content.ToString() == "first");
    buttonFirst.Background = Brushes.Yellow;