Search code examples
wpfresourcedictionary

Accessing buttons which are in ResourceDictionary from codebehind


I have a WPF project with a folder Themes in which there is a Generic.xaml file which looks like this:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ikea.Master">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Style/Master.xaml" />
    </ResourceDictionary.MergedDictionaries>

    <Style TargetType="{x:Type local:Master}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:Master}">
            <StackPanel>

                        <StackPanel Margin="10" Orientation="Horizontal">
                            <Button Style="{StaticResource RoundCorner}" Name="btn1"  Command="NavigationCommands.GoToPage" CommandParameter="ViewModel/Back.xaml" CommandTarget="{Binding ElementName=frmContent}" ></Button>
                            <Button Style="{StaticResource RoundCorner}" Name="btn2" Command="NavigationCommands.GoToPage" CommandParameter="ViewModel/Home.xaml" CommandTarget="{Binding ElementName=frmContent}" ></Button>
                            <Button Style="{StaticResource RoundCorner}" Name="btn3" Command="NavigationCommands.GoToPage" CommandParameter="ViewModel/Help.xaml" CommandTarget="{Binding ElementName=frmContent}" ></Button>

            </StackPanel >

            </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

In the Master.xaml file I define a style for RoundCorner.

Now, what I want to do is change the content of the buttons via code behind of the Back.xaml, Home.xaml, etc. These buttons appear on all of my pages. How can I access btn1, btn2, btn3 from code behind?

Application.Current.Resources gives me nothing.


Solution

  • You may use VisualTreeHelper class if your elements already rendered. Here is some rough method that is supposed to find buttons for you, if it help - redesign it for your needs

        public static IEnumerable<Button> FindButtons(DependencyObject container, string name)
        {
            if (container == null)
            {
                yield break;
            }
    
            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(container); i++)
            {
                var child = VisualTreeHelper.GetChild(container, i);
                var button = child as Button;
    
                if (button != null && button.Name == name)
                {
                    yield return button;
                }
    
                foreach (var childOfChild in FindButtons(child, name))
                {
                    yield return childOfChild;
                }
            }
        }
    

    You are supposed to get a bunch of buttons that fits specified name.