Question

I would like to achieve something that when thinking about it seems very straightforward.

I have a MVVM application of sorts, where I have a window with multiple pages/views and along the top I have an itemscontrol of buttons which take you to the various pages. Now I'd like the current pages button to change colour and stay that way while you're on the page.

Here is some of my code:

<DockPanel>
    <Border DockPanel.Dock="Top" BorderBrush="#FAAA" BorderThickness="0,0,0,3" Background="#FDDD">
        <ItemsControl ItemsSource="{Binding PageViewModels}">
            <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Width="75"
                            Height="30"
                            Content="{Binding Name}"
                            Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                            CommandParameter="{Binding }"
                            Style="{StaticResource MenuButton}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Border>

    <ContentControl Content="{Binding CurrentPageViewModel}" />
</DockPanel>

I was told that Data triggers may help but I don't know how to implement that into an itemscontrol. Will I have to break it apart, display all the buttons manually and then set it based on name or something?

Thanks

Was it helpful?

Solution

WPF already have a control that does the described behavior called TabControl. It can be styled to look like buttons if you prefer instead of regular tabs, just modify the control template for tab items. Below is some sample code making the selected tab red.

XAML:

<Window x:Class="WpfApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>

        <LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FFF" Offset="0.0"/>
                    <GradientStop Color="#EEE" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />

        <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />

        <SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" />

        <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

        <Style TargetType="{x:Type TabItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid>
                            <Border 
                                Name="Border"
                                Margin="0,0,-4,0" 
                                Background="{StaticResource LightBrush}"
                                BorderBrush="{StaticResource SolidBorderBrush}" 
                                BorderThickness="1,1,1,1" 
                                CornerRadius="2,12,0,0" >
                                <ContentPresenter x:Name="ContentSite"
                                    VerticalAlignment="Center"
                                    HorizontalAlignment="Center"
                                    ContentSource="Header"
                                    Margin="12,2,12,2"
                                    RecognizesAccessKey="True"/>
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Panel.ZIndex" Value="100" />
                                <Setter TargetName="Border" Property="Background" Value="Red" />
                                <Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
                                <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
                                <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>

    <StackPanel>

        <TabControl 
            ItemsSource="{Binding Path=PageViewModels}">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Header}" />
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Content}" />
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>

    </StackPanel>

</Window>

Code behind:

using System.Collections.Generic;
using System.Windows;

namespace WpfApplication
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = this;
        }

        public List<PageViewModel> PageViewModels
        {
            get
            {
                return new List<PageViewModel>() { new PageViewModel() { Header = "A", Content = "AAA" }, new PageViewModel { Header = "B", Content = "BBB" } };
            }
        }
    }

    public class PageViewModel
    {
        public string Header { get; set; }

        public string Content { get; set; }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top