How to bind click of a button to change the content of a panel (Grid) using XAML

10,950

I think the XAML-only solution you choose will depend on your specific requirements. In the examples below, I am assuming that XAML-only means you are looking for a solution that does not involve binding to properties in your ViewModel.

Approach #1:

If you decide to use a single ToggleButton to show and hide your panel, then this can be done quite easily using Triggers:

<Window x:Class="WpfApplication1.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">
    <ContentControl>
        <ContentControl.Template>
            <ControlTemplate>
                <StackPanel>
                    <Grid x:Name="myGrid" Background="Beige" Height="100">
                        <TextBlock Text="Content Placeholder" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"/>
                    </Grid>
                    <ToggleButton x:Name="toggleButton" Content="Show\Hide Panel" IsChecked="True"/>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger SourceName="toggleButton" Property="IsChecked" Value="True">
                        <Setter TargetName="myGrid" Property="Visibility" Value="Visible" />
                    </Trigger>
                    <Trigger SourceName="toggleButton" Property="IsChecked" Value="False">
                        <Setter TargetName="myGrid" Property="Visibility" Value="Hidden" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </ContentControl.Template>
    </ContentControl>
</Window>

Approach #2:

If instead you require two buttons (one for showing the panel, one for hiding the panel), then perhaps you could use an EventTrigger instead. This solution is more heavy handed since an EventTrigger does not use Setter's but instead its action is required to be a Storyboard. To emulate the setting of a property like Visibility you can use ObjectAnimationUsingKeyFrames in your Storyboard:

<Window x:Class="WpfApplication1.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">
    <StackPanel>
        <Grid x:Name="myGrid" Background="Beige" Height="100">
            <TextBlock Text="Content Placeholder" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"/>
        </Grid>
        <Button x:Name="showPanelButton" Content="Show Panel" />
        <Button x:Name="hidePanelButton" Content="Hide Panel" />
        <StackPanel.Triggers>
            <EventTrigger RoutedEvent="UIElement.PreviewMouseLeftButtonUp" SourceName="showPanelButton">
                <BeginStoryboard>
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="myGrid" Storyboard.TargetProperty="(UIElement.Visibility)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
            <EventTrigger RoutedEvent="UIElement.PreviewMouseLeftButtonUp" SourceName="hidePanelButton">
                <BeginStoryboard>
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="myGrid" Storyboard.TargetProperty="(UIElement.Visibility)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </StackPanel.Triggers>
    </StackPanel>
</Window>

Hope this helps!

Share:
10,950
SpeedBirdNine
Author by

SpeedBirdNine

I am a software engineer and hobbyist gamer. Other than that I like reading and exploring new technologies. Me on Twitter My favorite questions: What is the single most influential book every programmer should read? Why is subtracting these two times (in 1927) giving a strange result? MVVM: Tutorial from start to finish? What is the worst gotcha in C# or .NET? Learning game programming byte + byte = int… why? Fastest sort of fixed length 6 int array Where do you go to tickle your brain (to get programming challenges)? What modern C++ libraries should be in my toolbox? Why is my program slow when looping over exactly 8192 elements? Learning to Write a Compiler

Updated on June 04, 2022

Comments

  • SpeedBirdNine
    SpeedBirdNine almost 2 years

    I am creating a UI of a WPF Application, and while working on the implementation of the software's features, i didn't have much experience with creating the UI.

    Now I need to a way to change the contents of the Properties panel which has a grid to contain the content. I have created multiple panels, hidden all but one, and now i want to switch when the user clicks on a button in the Ribbon on the top, (or it could be any button somewhere else in the layout).

    It is very easy to do with code, but i want to do it without any code, using only XAML. How to do it?

    Also how to bind the similar behavior to other items on the UI?

  • SpeedBirdNine
    SpeedBirdNine over 12 years
    Due to some reason, the program hangs and debugger pops up!
  • FunnyItWorkedLastTime
    FunnyItWorkedLastTime over 12 years
    I created this example using a .NET 4.0 project. In a .NET 3.5 project you will get an error indicating that WPF does not know how to convert a string ("PreviewMouseLeftButtonUp") to a RoutedEvent. I have edited the above example by explicitly specifying the RoutedEvent as UIElement.PreviewMouseLeftButtonUp, this should work now.
  • SpeedBirdNine
    SpeedBirdNine over 12 years
    Using .NET 4.0, see this question: stackoverflow.com/questions/7702176/…