Windows Phone Equivalent of a WinRT ContentControl - c#

I am trying to port a custom content control class from a WinRT app to a Windows Phone 8 app, but I cannot figure out exactly how to accomplish it. I essentially want to port something like the following:
MenuPanel.cs
public sealed class MenuPanel : ContentControl
{
#region ContentVisibility
/// <summary>
/// ContentVisibility Dependency Property
/// </summary>
public static readonly DependencyProperty ContentVisibilityProperty =
DependencyProperty.Register(
"ContentVisibility",
typeof(Visibility),
typeof(MenuPanel),
new PropertyMetadata(Visibility.Visible, null));
/// <summary>
/// Gets or sets the ContentVisibility property
/// </summary>
public Visibility ContentVisibility
{
get { return (Visibility)GetValue(ContentVisibilityProperty); }
set { SetValue(ContentVisibilityProperty, value); }
}
#endregion
... Lots more, but truncated for brevity
}
Generics.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Expansion.WinRT.Controls">
<Style TargetType="local:MenuPanel">
<Setter Property="ContentVisibility" Value="Visible" />
<Setter Property="EnableVisibility" Value="Collapsed" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MenuPanel">
<Grid>
<Border BorderBrush="#33FFFFFF" BorderThickness="16" CornerRadius="1" />
<Border BorderBrush="#4CFFFFFF" BorderThickness="8" CornerRadius="1" Margin="4" />
<Border BorderBrush="White" Background="#26FFFFFF" BorderThickness="2" CornerRadius="1" Margin="7" Padding="3">
<StackPanel>
<ContentPresenter
Visibility="{TemplateBinding ContentVisibility}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" />
<Button
Name="EnableButton"
Visibility="{TemplateBinding EnableVisibility}"
BorderBrush="Transparent"
Content="+"
FontSize="40"
Padding="0,-10,0,0"
HorizontalAlignment="Center"
Width="70" />
</StackPanel>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MainPage.xaml
...
<local:MenuPanel Name="MainMenuPanel" Width="520" VerticalAlignment="Center">
<StackPanel>
<StackPanel Name="StartMenu" Visibility="Visible">
<Button Name="NewGameButton" Content="New Game" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Transparent" FontSize="30" />
<Button Name="LoadGameButton" Content="Load Game" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Transparent" FontSize="30" />
<Button Name="OptionsButton" Content="Options" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Transparent" FontSize="30" />
</StackPanel>
</StackPanel>
</local:MenuPanel>
...
I took a look at http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.controls.contentcontrol(v=vs.105).aspx but it didn't help much.

Related

How to hide or change background of previous and next buttons for Microsoft.UI.Xaml.Controls.Calendarview

im having a hard time to find a way to hide previous and next buttons for a CalendarView control, the reason why i want to do this is to avoid user confusion since those are disabled anyways. The CalendarView min and max dates are set to only 1 specific month, ie: (1 January 2023 to 31 January 2023).
The previous and next arrows are automatically disabled as intended, however i want to go a step further and make said arrows invisible.
Below you can find XAML Code for reference.
<VariableSizedWrapGrid
Margin="0,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<VariableSizedWrapGrid.ChildrenTransitions>
<TransitionCollection>
<RepositionThemeTransition />
<EntranceThemeTransition
FromHorizontalOffset="-200"
FromVerticalOffset="0"
IsStaggeringEnabled="False" />
</TransitionCollection>
</VariableSizedWrapGrid.ChildrenTransitions>
<CalendarView
x:Name="januaryCalendar"
x:FieldModifier="Public"
CornerRadius="20" />
</VariableSizedWrapGrid>
And C# code behind to set min and max dates for said control:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
januaryCalendar.MinDate = new DateTime(DateTime.Now.Year,1,1);
januaryCalendar.MaxDate = new DateTime(DateTime.Now.Year, 1, 31);
}
These Buttons are named, PreviousButton and NextButton.
You can bring the DefaultCalendarViewStyle from generic.xaml and change the Opacity to "0" when they are disabled.
First, create a converter because Enabled is bool and Opacity is double.
DisabledToZeroOpacityConverter.cs
using Microsoft.UI.Xaml.Data;
using System;
namespace CalendarViewTests;
public class DisabledToZeroOpacityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return (value is bool enabled && enabled is true)
? 1.0
: 0.0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Bring the DefautCalendarViewStyle and change the Opacity like this.
NOTE: The resources below are abbreviated due to the max characters in an answer.
MainPage.xaml
<Page
x:Class="CalendarViewTests.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalendarViewTests"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Page.Resources>
<local:DisabledToZeroOpacityConverter x:Key="DisabledToZeroOpacityConverter" />
<Style
x:Key="CustomCalendarViewStyle"
BasedOn="{StaticResource DefaultCalendarViewStyle}"
TargetType="CalendarView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CalendarView">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Border.Resources>
...
</Border.Resources>
<Grid
MinWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.MinViewWidth}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button
x:Name="HeaderButton"
HorizontalContentAlignment="Left"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.HeaderText}"
IsEnabled="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.HasMoreViews}"
Style="{StaticResource HeaderNavigationButtonStyle}" />
<!-- PreviousButton -->
<Button
x:Name="PreviousButton"
Grid.Column="1"
Margin="{ThemeResource CalendarViewNavigationPreviousButtonMargin}"
HorizontalContentAlignment="Center"
Content=""
IsEnabled="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.HasMoreContentBefore}"
Opacity="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource DisabledToZeroOpacityConverter}}"
Style="{StaticResource NavigationButtonStyle}" />
<!-- NextButton -->
<Button
x:Name="NextButton"
Grid.Column="2"
Margin="{ThemeResource CalendarViewNavigationNextButtonMargin}"
HorizontalContentAlignment="Center"
Content=""
IsEnabled="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.HasMoreContentAfter}"
Opacity="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource DisabledToZeroOpacityConverter}}"
Style="{StaticResource NavigationButtonStyle}" />
</Grid>
<Border
Grid.Row="1"
Height="1"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1" />
<Grid
x:Name="Views"
Grid.Row="2">
...
</Grid>
</Grid>
<VisualStateManager.VisualStateGroups>
...
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<VariableSizedWrapGrid
Margin="0,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<VariableSizedWrapGrid.ChildrenTransitions>
<TransitionCollection>
<RepositionThemeTransition />
<EntranceThemeTransition
FromHorizontalOffset="-200"
FromVerticalOffset="0"
IsStaggeringEnabled="False" />
</TransitionCollection>
</VariableSizedWrapGrid.ChildrenTransitions>
<CalendarView
x:Name="januaryCalendar"
x:FieldModifier="Public"
CornerRadius="20"
Style="{StaticResource CustomCalendarViewStyle}" />
</VariableSizedWrapGrid>
</Page>

WPF Style with multiple contents

I have created a style that creates a Label as a circle with the text in the middle.
<Style x:Key="RoundedLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Grid Height="Auto" Width="Auto" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Ellipse x:Name="cp" Margin="0,0,0,0" Fill="{TemplateBinding Background}" Height="{TemplateBinding Width}" Width="{TemplateBinding Width}" Stroke="Black" StrokeThickness="2" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Content>
<Border Padding="10">
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Its used in this way:
<Label Style="{StaticResource RoundedButtonStyle}" Content="{Binding CountValue}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" />
This works fine.
However I want to add further information to this label by having two text fields in different locations.
The first one already exists and displays in the centre of the ellipse.
Id like to add one which displays underneath the Ellipse.
Id like to be able to implement it in pure xaml if it is possible and use it something like this where the binding to SecondLabelText shows under the Ellipse:
<Label Style="{StaticResource RoundedButtonStyle}" Content="{Binding CountValue}" SecondContent="{Binding SecondLabelText}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" />
I can add the label into the style, but how do i set two separate contents?
Don't know if this is any use to you; went away and created this as a custom user control as a bit of a practice, You can create a new user control, setting 2 properties to receive the 2 contents:
using System.Windows;
using System.Windows.Controls;
namespace Custom_Control_Elipse_2_labels
{
/// <summary>
/// Interaction logic for EllipseWithTwoLabels.xaml
/// </summary>
public partial class EllipseWithTwoLabels : UserControl
{
public static readonly DependencyProperty Content1Property = DependencyProperty.Register("Content1", typeof(string), typeof(EllipseWithTwoLabels));
public static readonly DependencyProperty Content2Property = DependencyProperty.Register("Content2", typeof(string), typeof(EllipseWithTwoLabels));
public EllipseWithTwoLabels()
{
InitializeComponent();
DataContext = this;
}
public string Content1
{
get => (string) GetValue(Content1Property);
set => SetValue(Content1Property,value);
}
public string Content2
{
get => (string)GetValue(Content2Property);
set => SetValue(Content2Property, value);
}
}
}
The .xaml for the user control being
<Grid>
<Label Content="{Binding Content1}" Style="{StaticResource RoundedButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" ></Label>
<Label Content="{Binding Content2}" Margin="0,150,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" ></Label>
</Grid>
You can then just import it into any view to use it with: (
xmlns:local="clr-namespace:Custom_Control_Elipse_2_labels"
And use with the xaml:
<local:EllipseWithTwoLabels Height="300" Width="300" Content1="Content #1" Content2="Content #2"/>
Is one way to get it done :)
It provides something like this:
You can use for example Tag property of label to store extra data
<Label Style="{StaticResource RoundedLabelStyle}" Content="Content" Tag="Content#2"/>
In template just bind to Tag property
<ContentPresenter Content="{TemplateBinding Tag}"/>
Better approach is to use AttachedProperty. This allow you declare as many extra content as you want, without creating new type of control
public class LabelExtension
{
public static readonly DependencyProperty SecondContentProperty = DependencyProperty.RegisterAttached(
"SecondContent", typeof(object), typeof(LabelExtension));
public static void SetSecondContent(UIElement element, object value)
{
element.SetValue(SecondContentProperty, value);
}
public static object GetSecondContent(UIElement element)
{
return (object)element.GetValue(SecondContentProperty);
}
}
Set it on control
<Label Style="{StaticResource RoundedLabelStyle}" Content="Content" local:LabelExtension.SecondContent="Content#2"/>
Use from within template
<ContentPresenter Content="{TemplateBinding local:LabelExtension.SecondContent}"/>
Complete label style example
<Style x:Key="RoundedLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Grid Height="Auto" Width="Auto" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Ellipse x:Name="cp" Margin="0,0,0,0" Fill="{TemplateBinding Background}" Height="{TemplateBinding Width}" Width="{TemplateBinding Width}" Stroke="Black" StrokeThickness="2" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Content>
<Border Padding="10">
<StackPanel>
<ContentPresenter Content="{TemplateBinding Content}"/>
<ContentPresenter Content="{TemplateBinding Tag}"/>
<ContentPresenter Content="{TemplateBinding local:LabelExtension.SecondContent}"/>
</StackPanel>
</Border>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Cant set 3 toggle button text content which use same style

i have three toggle buttons which use a singe style resource on wpf, now i cant set their content, content is declared more than once error, each toggle button has a different content.
Each toggle button uses an image as background also.
<UserControl.Resources>
<Style x:Key="Chromeless" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border BorderThickness="0" Width="197" Height="60">
<ContentPresenter TextElement.FontFamily="{TemplateBinding TextElement.FontFamily}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,0,0,0"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Image x:Key="page1Pressed" Source="/graph_engine;Component/cucaracha/LD3/button_1.png" Height="60" Width="197" />
<Image x:Key="page1" Source="/graph_engine;Component/cucaracha/LD3/button_1_pressed.png" Height="60" Width="197" />
<Image x:Key="page2Pressed" Source="/graph_engine;Component/cucaracha/LD3/button_2.png" Height="60" Width="197" />
<Image x:Key="page2" Source="/graph_engine;Component/cucaracha/LD3/button_2_pressed.png" Height="60" Width="197" />
<Image x:Key="page3Pressed" Source="/graph_engine;Component/cucaracha/LD3/button_3.png" Height="60" Width="197" />
<Image x:Key="page3" Source="/graph_engine;Component/cucaracha/LD3/button_3_pressed.png" Height="60" Width="197" />
</UserControl.Resources>
<Viewbox Stretch="Fill" StretchDirection="Both">
<Grid Height="60" Name="grid1" Width="591" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="197" />
<ColumnDefinition Width="197" />
<ColumnDefinition Width="197" />
</Grid.ColumnDefinitions>
<ToggleButton Style="{StaticResource Chromeless}" Name="page1" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Foreground="{x:Null}" Checked="page1_Checked" Unchecked="page1_Unchecked">
<DynamicResource ResourceKey="page1"/>
</ToggleButton>
<ToggleButton Grid.Column="1" Style="{StaticResource Chromeless}" Name="page2" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Foreground="{x:Null}" Unchecked="page2_Unchecked" Checked="page2_Checked">
<DynamicResource ResourceKey="page2"/>
</ToggleButton>
<ToggleButton Grid.Column="2" Style="{StaticResource Chromeless}" Name="page3" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Foreground="{x:Null}" Checked="page3_Checked" Unchecked="page3_Unchecked">
<DynamicResource ResourceKey="page3"/>
</ToggleButton>
</Grid>
</Viewbox>
Do you mean you can't change the image when you pressed down the toggle button? You only set a image to the content of toggle button. You can use Visual State Manager to change the background like this
If you just want to set the image and failed. Please check the image path.

WPF DataGrid Dock panel grouping

I'm using wpf datagrid, and I'm using grouping to group my orders by number of order, and I also have a status for each order item, like : is it proceed or not, but somehow it looks messy on screen if I list each status for each item, because if one item of each order is proceed that means all of items are also proceed, so I'm wondering is it possible to move status next to Order number (Expander header - DockPanel) so I might get look like this:
Order number :# 1 - Order is in progress.
Order number :# 2 - Order is in progress.
Order number :# 3 - Order is not in progress.
So question is:
IS IT POSSIBLE TO MOVE 'ORDER STATUS' NEXT TO Order Number part?:)
Here is my code:
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="Black" Opacity="0.7">
<Expander.Header >
<DockPanel Height="50" Margin="0,0,0,0" Name="dockPanel" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=ActualWidth}">
<Button Name="btnFinishOrder" Content="Finish order" Margin="0,0,55,5" DockPanel.Dock="Right" Click="btnFinishOrder_Click" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Name="btnTakeIt" Click="btnTakeIt_Click" Content="Take it!" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Path=Name,StringFormat= Order Number:# {0}}" />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
code behind:
public partial class MainWindow : Window
{
CollectionViewSource collectionViewSource = new CollectionViewSource();
public MainWindow()
{
try
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.WindowState = WindowState.Maximized;
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = ordersList;
collectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder"));
DataContext = collectionViewSource;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1000);
timer.Tick += timer_Tick;
timer.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
The Expander.Header does not get one of your view models as DataContext. Instead the header gets an object that inherits from CollectionViewGroup. One of its properties is Name. That's why you can bind to Name in your XAML
<TextBlock ... Text="{Binding Path=Name,StringFormat= Order Number:# {0}}" />
Another property of interest is Items. That's the list of all view models of that group. Now it's easy to access an item's property in the header
<TextBlock ... Text="{Binding Path=Items[0].MyProperty}" />

Grouping items in a vertical TabControl

Current situation
This is a styled TabControl I'm using as a sidebar menu for my program. The grey area on the right hand is where the TabItem's content would go. I've added some sample text as an example.
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid ClipToBounds="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Background="{StaticResource Accent1_2}" Grid.Column="0" Grid.Row="0" />
<Border BorderBrush="{StaticResource Accent1_1}" Background="{StaticResource Accent1_3}" Grid.Column="0" Margin="40" Grid.Row="0" BorderThickness="1" VerticalAlignment="Top">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{TemplateBinding Tag}" VerticalAlignment="Center" FontSize="18" Margin="5,8,0,8" />
<StackPanel x:Name="HeaderPanel" Grid.Row="1" Orientation="Vertical" IsItemsHost="True" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1" />
</Grid>
</Border>
<Grid x:Name="ContentPanel" Grid.Column="1" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentTemplate="{TemplateBinding SelectedContentTemplate}" Content="{TemplateBinding SelectedContent}" ContentStringFormat="{TemplateBinding SelectedContentStringFormat}" ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</Grid>
</ControlTemplate>
...
<DataTemplate DataType="{x:Type TabItem}">
<Border x:Name="ContentBorder" Background="White" Height="30">
<TextBlock x:Name="ContentTextBlock" Margin="5,0,0,0" Foreground="SteelBlue" FontSize="14" Text="{TemplateBinding Content}" VerticalAlignment="Center" />
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}}" Value="True">
<Setter TargetName="ContentTextBlock" Property="Foreground" Value="{StaticResource Accent1_4}" />
<Setter TargetName="ContentBorder" Property="Background" Value="{StaticResource Accent1_1}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
My goal
However, I'd like to group some of the items into another box, so that the control would look like this:
How can I acheive this look of the TabControl?
I would drop the TabControl idea completely, and just display data with a ContentPresenter
So your DataModel would have
public ObservableCollection<IItemBase> Items { get; set; }
public ObservableCollection<IItemBase> SpecialItems { get; set; }
public IItemBase SelectedItem { get; set; }
And your UI would be something like
<DockPanel>
<StackPanel Style="{staticResource NavBarStyle}" DockPanel.Dock="Left">
<ListBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" />
<ListBox ItemsSource="{Binding SpecialItems}" SelectedItem="{Binding SelectedItem}" />
</StackPanel>
<ContentPresenter Content="{Binding SelectedItem}" />
</DockPanel>
You might have to tinker with the exact implementation of SelectedItem so it binds correctly to both ListBoxes, but it shouldn't be that hard to get working if that gives you any problems.

Categories