I am new to WPF and am struggling to put the pieces of information together. I am trying to create a two level vertical menu like the one here. I have achieved my desired look by overriding the control template of tree view items.
Here is my code.
<BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
<Style x:Key="MenuText" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
<Setter Property="Foreground" Value="#FFA7B1C2"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style x:Key="MenuIcon" TargetType="TextBlock" BasedOn="{StaticResource BaseIconTextBlockStyle}">
<Setter Property="Foreground" Value="#FFA7B1C2"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style x:Key="MenuToggleButton" TargetType="ToggleButton">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Height" Value="46"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="MenuItemNormal" TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton Grid.Row="0" Tag="{TemplateBinding Tag}" Content="{TemplateBinding Header}" Style="{StaticResource MenuToggleButton}" >
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="Border" BorderBrush="Transparent" >
<StackPanel Orientation="Horizontal" Background="{TemplateBinding Background}" Margin="25,0" >
<TextBlock x:Name="Icon" Style="{StaticResource MenuIcon}" Text="{TemplateBinding Tag}"/>
<TextBlock x:Name="MenuText" Style="{StaticResource MenuText}" Text="{TemplateBinding Content}" Margin="6,0,0,0"/>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF293846"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Icon">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="MenuText">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="Border">
<EasingThicknessKeyFrame KeyTime="0" Value="4,0,0,0"/>
</ThicknessAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0" Value="#FF19AA8D"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<StackPanel Grid.Row="1" Visibility="Visible">
<ItemsPresenter />
</StackPanel>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="MenuItemParent" TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="MenuButton" Grid.Row="0" Tag="{TemplateBinding Tag}" Content="{TemplateBinding Header}" Style="{StaticResource MenuToggleButton}" >
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="Border" BorderBrush="Transparent" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" Background="{TemplateBinding Background}" Margin="25,0" >
<TextBlock x:Name="Icon" Style="{StaticResource MenuIcon}" Text="{TemplateBinding Tag}"/>
<TextBlock x:Name="MenuText" Style="{StaticResource MenuText}" Text="{TemplateBinding Content}" Margin="6,0,0,0"/>
</StackPanel>
<TextBlock x:Name="Chevron" Grid.Column="1" Style="{StaticResource MenuIcon}" Text="" Margin="0,0,20,0"/>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF293846"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Icon">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="MenuText">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Chevron">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="Border">
<EasingThicknessKeyFrame KeyTime="0" Value="4,0,0,0"/>
</ThicknessAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0" Value="#FF19AA8D"/>
</ColorAnimationUsingKeyFrames>
<StringAnimationUsingKeyFrames Storyboard.TargetProperty="(TextBlock.Text)" Storyboard.TargetName="Chevron">
<DiscreteStringKeyFrame KeyTime="0" Value=""/>
</StringAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</ToggleButton.Template>
<ToggleButton.Triggers>
<EventTrigger RoutedEvent="ToggleButton.Checked">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetName="ChildContainer" Storyboard.TargetProperty="RenderTransform.ScaleY" From="0" To="1" Duration="0:00:.500"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="ToggleButton.Unchecked">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetName="ChildContainer" Storyboard.TargetProperty="RenderTransform.ScaleY" From="1" To="0" Duration="0:00:.500"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ToggleButton.Triggers>
</ToggleButton>
<StackPanel x:Name="ChildContainer" Grid.Row="1" Visibility="{Binding IsChecked, ElementName=MenuButton, Converter={StaticResource BooleanToVisibility}}">
<StackPanel.RenderTransform>
<ScaleTransform ScaleY="0"></ScaleTransform>
</StackPanel.RenderTransform>
<ItemsPresenter />
</StackPanel>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="MenuItemChild" TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton Grid.Row="0" Tag="{TemplateBinding Tag}" Content="{TemplateBinding Header}" Style="{StaticResource MenuToggleButton}" >
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="Border" BorderBrush="Transparent" Background="#FF293846">
<StackPanel Grid.Column="0" Orientation="Horizontal" Background="{TemplateBinding Background}" Margin="25,0" >
<TextBlock x:Name="Icon" Style="{StaticResource MenuIcon}" Text=""/>
<TextBlock x:Name="MenuText" Style="{StaticResource MenuText}" Text="{TemplateBinding Content}" Margin="6,0,0,0"/>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF293846"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Icon">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="MenuText">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="Border">
<EasingThicknessKeyFrame KeyTime="0" Value="4,0,0,0"/>
</ThicknessAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0" Value="#FF19AA8D"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<StackPanel Grid.Row="1" Visibility="Visible">
<ItemsPresenter />
</StackPanel>
</Grid>
</ControlTemplate>
And in my Window I declare Treeview like this.
<TreeView x:Name="Menu" Background="Transparent" BorderThickness="0">
<TreeViewItem Tag="" Header="Dashboard" Template="{StaticResource MenuItemNormal}" />
<TreeViewItem Tag="" Header="Home" Template="{StaticResource MenuItemNormal}" />
<TreeViewItem Tag="" Header="Reporting" Template="{StaticResource MenuItemNormal}" />
<TreeViewItem Tag="" Header="Sell" Template="{StaticResource MenuItemNormal}" />
<TreeViewItem Tag="" Header="Products" Template="{StaticResource MenuItemParent}" >
<TreeViewItem Header="Item 2.1" Template="{StaticResource MenuItemChild}" />
<TreeViewItem Header="Item 2.2" Template="{StaticResource MenuItemChild}" />
</TreeViewItem>
<TreeViewItem Tag="" Header="Sales Ledger" Template="{StaticResource MenuItemNormal}" />
<TreeViewItem Tag="" Header="Customers" Template="{StaticResource MenuItemNormal}" />
<TreeViewItem Tag="" Header="Setup" Template="{StaticResource MenuItemNormal}" />
</TreeView>
The problem is that now I realize I should have probably overridden the data
template of the tree view item because I want to bind the tree view to a property on my view model. I cannot figure out if I use data template how do I remove the default ugly expander icon that comes with tree view items
Specifically I have 3 questions
Is overriding control template the right way to achieve what I am
trying to do?
How do I bind my tree view to a view model property
instead of hard coding the items?
How do I track the selected item in my view model?
Thank you in advance!
I am having multiple sections in pivot item with a same Item Template.
Below is my xaml part of the pivot
<Page
x:Class="Namespace.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Namespace"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModels="Namespace.ViewModels"
xmlns:q42controls="using:Q42.WinRT.Controls"
mc:Ignorable="d">
<Page.Resources>
<ViewModels:ViewModel x:Key="ViewModel" />
<DataTemplate x:Key="headerTemplate">
<TextBlock Text="{Binding Title}" FontSize="16"/>
</DataTemplate>
<DataTemplate x:Key="pivotTemplate">
<ListView x:Name="listView" Background="White" ItemsSource="{Binding Articles}"
HorizontalAlignment="Left" Margin="-25 0 -25 0" SelectionChanged="getIndex">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Tapped="StackPanel_Tapped">
<Grid>
<Grid.Background>
<ImageBrush AlignmentX="Center" AlignmentY="Center" ImageSource="Assets/PlaceHolder.jpg"></ImageBrush>
</Grid.Background>
<Image x:Name="ArticleImage" q42controls:ImageExtensions.CacheUri="{Binding ImageURL}"></Image>
</Grid>
<StackPanel>
<TextBlock x:Name="HeadLine" Text="{Binding HeadLine}"
Margin="10 5 10 -5" TextWrapping="Wrap"
FontSize="20"
FontFamily="{StaticResource HeadlineCommonFamiy}"
Pivot.SlideInAnimationGroup="GroupTwo"
FontWeight="Bold" TextTrimming="CharacterEllipsis" Height="63"/>
<TextBlock Text="{Binding Abstract}" TextWrapping="Wrap" FontSize="15"
Pivot.SlideInAnimationGroup="GroupTwo" Margin="10 5 0 10"
FontFamily="{StaticResource AbstractCommonFamily}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</Page.Resources>
<Page.BottomAppBar>
<CommandBar Foreground="Black" ClosedDisplayMode="Minimal" Background="White">
<CommandBar.PrimaryCommands>
<AppBarButton x:Uid="Refresh" Icon="Refresh" Label="Refresh" Tapped="RefreshButton_Tapped"/>
</CommandBar.PrimaryCommands>
<CommandBar.SecondaryCommands>
<AppBarButton x:Uid="Favourites" Icon="Favorite" Label="Favourites" Tapped="Favourites_Tapped"/>
<AppBarButton x:Uid="Settings" Icon="Setting" Label="Settings" Tapped="Settings_Tapped"/>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
<Grid Style="{StaticResource MyGridStyle}">
<Grid x:Name="LoadingGrid" Visibility="Visible">
<ProgressRing x:Name="progressRing" IsActive="True" Foreground="White" HorizontalAlignment="Center" Width="60"
Height="50" VerticalAlignment="Center" Margin="0 20 0 0"></ProgressRing>
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="45"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Image Source="Assets/_logo.png" HorizontalAlignment="Center" Margin="1 5 0 0"></Image>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content=""
Width="60" Height="60" Background="Transparent" Margin="-10 -20 0 0"
Click="HamburgerButton_Click" Foreground="White"/>
</Grid>
<Grid Grid.Column="1">
<TextBlock Text="சினிமா" HorizontalAlignment="Center" FontSize="30"
Margin="-50 0 0 0" Foreground="White"></TextBlock>
</Grid>
</Grid>
<Grid Grid.Row="2" x:Name="galleryGrid" Visibility="Collapsed">
<SplitView x:Name="MySplitView" DisplayMode="CompactOverlay" IsPaneOpen="False"
CompactPaneLength="0" OpenPaneLength="220">
<SplitView.Pane>
<ListView x:Name="menuBindList" Style="{StaticResource MyListViewStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal" Tag="{Binding SectionName}">
<TextBlock Text="{Binding TitleofAccess}"
Tag="{Binding SectionName}" FontSize="18"
VerticalAlignment="Center" Foreground="White" Tapped="MenuTextBlock_Tapped" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</SplitView.Pane>
<SplitView.Content>
<ScrollViewer Name="cinemaScroll">
<Pivot DataContext="{StaticResource ViewModel}" x:Name="galleryPivot"
HeaderTemplate="{StaticResource headerTemplate}"
ItemTemplate="{StaticResource pivotTemplate}" ItemsSource="{Binding Feeds}"
Margin="0,-10,0,10" SelectionChanged="galleryPivot_SelectionChanged">
<Pivot.Resources>
<Style TargetType="PivotHeaderItem">
<Setter Property="CharacterSpacing" Value="{ThemeResource PivotHeaderItemCharacterSpacing}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
<Setter Property="Padding" Value="{ThemeResource PivotHeaderItemMargin}" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="RequestedTheme" Value="Dark" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="PivotHeaderItem">
<Grid
x:Name="Grid"
Background="{TemplateBinding Background}">
<Grid.Resources>
<Style x:Key="BaseContentPresenterStyle" TargetType="ContentPresenter">
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="LineStackingStrategy" Value="MaxHeight"/>
<Setter Property="TextLineBounds" Value="Full"/>
<Setter Property="OpticalMarginAlignment" Value="TrimSideBearings"/>
</Style>
<Style x:Key="BodyContentPresenterStyle" TargetType="ContentPresenter" BasedOn="{StaticResource BaseContentPresenterStyle}">
<Setter Property="FontFamily" Value="{ThemeResource PivotHeaderItemFontFamily}" />
<Setter Property="FontWeight" Value="{ThemeResource PivotHeaderItemThemeFontWeight}"/>
<Setter Property="FontSize" Value="{ThemeResource PivotHeaderItemFontSize}"/>
</Style>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualStateGroup.Transitions>
<VisualTransition From="Unselected" To="UnselectedLocked" GeneratedDuration="0:0:0.33" />
<VisualTransition From="UnselectedLocked" To="Unselected" GeneratedDuration="0:0:0.33" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unselected" />
<VisualState x:Name="UnselectedLocked">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ContentPresenterTranslateTransform"
Storyboard.TargetProperty="X"
Duration="0" To="{ThemeResource PivotHeaderItemLockedTranslation}" />
<DoubleAnimation Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="(UIElement.Opacity)"
Duration="0" To="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Background" >
<DiscreteObjectKeyFrame KeyTime="0" Value="#FF42424C" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="UnselectedPointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Background" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedPointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Background" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="UnselectedPressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Background" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedPressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
Storyboard.TargetProperty="Background" >
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter
x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Margin="{TemplateBinding Padding}"
FontSize="{TemplateBinding FontSize}"
FontFamily="{TemplateBinding FontFamily}"
FontWeight="{TemplateBinding FontWeight}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<ContentPresenter.RenderTransform>
<TranslateTransform x:Name="ContentPresenterTranslateTransform" />
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Pivot.Resources>
</Pivot>
</ScrollViewer>
</SplitView.Content>
</SplitView>
</Grid>
</Grid>
</Grid>
</Page>
I need to change the Item Template for a specific section dynamically. How can i achieve this. The section will contains image and we need to change the whole Item template and there we have redirection inside the pivot. How to obtain the scenario.
Below is the image design need to bind for the particular section
1st list of items like below
Likewise it contains list of items. In tapping of each section
redirect to the below
In tapping of single image take us to
Tapping will redirect to the below part
The above process will be carried out in a single pivot item. Will it be possible. If it's possible how to attain this. Please someone guide me to solve this
As per my understanding would suggest some of the methods in which you can achieve this
<Pivot >...
<PivotItem x:Uid="OVERVIEW" Header="" Margin="0">
<Grid>...
</Grid>
</PivotItem>.......
</Pivot>
Would be specifying ItemTemplate for the specific pivot inside that pivot Item. If the changes are specific for each pivot
Another way would be using this Link You can instead even use Converters and based on your data can make grids visible invisible etc. But you will need to identify what your triggers for ItemTemplate changed are based on.
My first question!
I'm looking to create a single row of text-filled buttons in XAML (kind of like this, but without the icons: http://bootsnipp.com/img/screenshots/0f277634083d2f5fd6c1bb54688da5b9b39bbc26.png), one of which can be selected at a time, similar to radio buttons. The RadioButton control has the right functionality, but the wrong aesthetic, and none of the styles or templates I've made seem to work correctly.
Is there any other control that would provide me with a way to create this row of buttons that keeps the functionality of the RadioButton? Or is there a way to template out the RadioButton so it looks like a text filled button?
Thanks!
Designing custom templates is hard :-), especially if you want to deal correctly with all possible state transitions (you can't change the same property of an object across different groups). Here's one I threw together for you though; there are a couple of TODOs if you want to change simple stuff (if you're more adventurous you can change other things, too).
First, the XAML: Paste this into your page, replacing everything except the opening and closing tags of the PhoneApplicationPage itself. You can also move the Resources to your App.xaml file if you want to use the style elsewhere:
<phone:PhoneApplicationPage.Resources>
<Style x:Key="TabControl" TargetType="RadioButton">
<Setter Property="Background" Value="Transparent"/>
<!--TODO: Change this BorderBrush if you want a different colour-->
<Setter Property="BorderBrush" Value="#4060ff"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="{StaticResource PhoneTouchTargetOverhang}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PressedBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ContentBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="CheckedBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="CheckedBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ContentBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="CheckedBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="DisabledBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!--TODO: Change this Margin if you don't like the big gaps between things-->
<Grid Margin="{StaticResource PhoneTouchTargetOverhang}">
<Border x:Name="ContentBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" />
<Border x:Name="PressedBorder" BorderBrush="{x:Null}" BorderThickness="0" Background="{TemplateBinding BorderBrush}" Opacity="0.75" Visibility="Collapsed" />
<Border x:Name="CheckedBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding BorderBrush}" Visibility="Collapsed"/>
<Border x:Name="DisabledBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Visibility="Collapsed" />
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<StackPanel VerticalAlignment="Center">
<Grid x:Name="container">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RadioButton Content="home" Grid.Column="0" Style="{StaticResource TabControl}" IsChecked="True"/>
<RadioButton Content="stuff" Grid.Column="1" Style="{StaticResource TabControl}" />
<RadioButton Content="info" Grid.Column="2" Style="{StaticResource TabControl}" />
<RadioButton Content="more..." Grid.Column="3" Style="{StaticResource TabControl}" />
</Grid>
<CheckBox x:Name="toggle" Content="show disabled" Checked="toggle_Checked" Unchecked="toggle_Unchecked"/>
</StackPanel>
</Grid>
Now a little bit of code to show enable / disable state:
private void toggle_Checked(object sender, RoutedEventArgs e)
{
foreach (var control in container.Children)
(control as RadioButton).IsEnabled = false;
}
private void toggle_Unchecked(object sender, RoutedEventArgs e)
{
foreach (var control in container.Children)
(control as RadioButton).IsEnabled = true;
}
I have a List box code in the XAML, below is my code:
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="2" Margin="12,0,12,0">
<ListBox Name="listBox"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
SelectionChanged="TopicListboxSelectionChanged"
ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,10" Orientation="Horizontal">
<Border Background="Gray">
<TextBlock Height="50"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding Path=Value}"></TextBlock>
</Border>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Now i need to add style to list box item, like the below image, along with onclick effect.
How to do it using Blend ? so that if i need to add styles to any other item tomorrow i can add it myself whithout seeking any help.
If there are any tutorials avaiable to learn, please provide me a link on that.
Declaring a style in a Page
Below all the namespace declaration in your page
Just make a tag
<phone:PhoneApplicationPage.Resources>
</phone:PhoneApplicationPage.Resources>
and declare the below style in it
<Style x:Key="style_ColorButton" TargetType="Button">
<Setter Property="Background" Value="Gray"/>
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
<Setter Property="Padding" Value="10,3,10,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="White"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Black">
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Gray"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0">
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Using this style with a button.
<Button Height="40" Width="40" Name="btnAcceptCrop" Click="btnAcceptCrop_Click" Style="{StaticResource style_ColorButton}"/>
This is basically a follow up to my previous question.
I've managed to make this work with the templates, however, I want to make it a bit generic, so that I don't have to go around repeating code all over the place
The working version (hardcoded) is this :
<UserControl.Resources>
<ControlTemplate x:Key="TrebleCheckboxImageTemplate" TargetType="CheckBox">
<Image x:Name="imgTreble" MinWidth="100" Source="Images/treble_checked.png">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="imgTreble" Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/treble_checked.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="imgTreble" Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/treble_unchecked.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Image>
</ControlTemplate>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="{StaticResource PhoneForegroundBrush}" Orientation="Horizontal">
<CheckBox Height="72" HorizontalAlignment="Left" Background="White" VerticalAlignment="Top" Template="{StaticResource TrebleCheckboxImageTemplate}" Margin="0,0,10,0" >
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<GalaSoft_MvvmLight_Command:EventToCommand CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Command="{Binding TreblePressedCommand}"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</CheckBox>
</StackPanel>
Of course, the image paths are hardcoded. So, i wanted to make it generic, so that you could just instantiate a checkbox, tell it it's image, and the template would be the same for all.
I created an ImageCheckbox control class :
public class ImageCheckbox : CheckBox
{
/// <summary>
/// The <see cref="CheckedImagePath" /> dependency property's name.
/// </summary>
public const string CheckedImagePathPropertyName = "CheckedImagePath";
/// <summary>
/// Gets or sets the value of the <see cref="CheckedImagePath" />
/// property. This is a dependency property.
/// </summary>
public string CheckedImagePath
{
get
{
return (string)GetValue(CheckedImagePathProperty);
}
set
{
SetValue(CheckedImagePathProperty, value);
}
}
/// <summary>
/// Identifies the <see cref="CheckedImagePath" /> dependency property.
/// </summary>
public static readonly DependencyProperty CheckedImagePathProperty = DependencyProperty.Register(
CheckedImagePathPropertyName,
typeof(string),
typeof(ImageCheckbox),
new PropertyMetadata(null));
/// <summary>
/// The <see cref="UnCheckedImagePath" /> dependency property's name.
/// </summary>
public const string UnCheckedImagePathPropertyName = "UnCheckedImagePath";
/// <summary>
/// Gets or sets the value of the <see cref="UnCheckedImagePath" />
/// property. This is a dependency property.
/// </summary>
public string UnCheckedImagePath
{
get
{
return (string)GetValue(UnCheckedImagePathProperty);
}
set
{
SetValue(UnCheckedImagePathProperty, value);
}
}
/// <summary>
/// Identifies the <see cref="UnCheckedImagePath" /> dependency property.
/// </summary>
public static readonly DependencyProperty UnCheckedImagePathProperty = DependencyProperty.Register(
UnCheckedImagePathPropertyName,
typeof(string),
typeof(ImageCheckbox),
new PropertyMetadata(null));
}
I created a converter (because I ran into the problem that I must convert the string to be the Uri for the image source)
public class StringToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return null;
}
if (!UriParser.IsKnownScheme("pack"))
{
UriParser.Register(new GenericUriParser
(GenericUriParserOptions.GenericAuthority), "pack", -1);
}
if (value is string)
{
var image = new BitmapImage();
image.UriSource = new Uri(String.Format(#"pack://application:,,/Images/{0}", value as string));
//image.UriSource = new Uri(String.Format(#"pack://application:,,,/Adagio.Presentation;component/Images/{0}", value as string),UriKind.Absolute);
image.ImageFailed += new EventHandler<System.Windows.ExceptionRoutedEventArgs>(image_ImageFailed);
image.ImageOpened += new EventHandler<System.Windows.RoutedEventArgs>(image_ImageOpened);
return image;
}
if (value is Uri)
{
var bi = new BitmapImage {UriSource = (Uri) value};
return bi;
}
return null;
}
void image_ImageOpened(object sender, System.Windows.RoutedEventArgs e)
{
throw new NotImplementedException();
}
void image_ImageFailed(object sender, System.Windows.ExceptionRoutedEventArgs e)
{
throw new NotImplementedException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
you can see that the converter has been tried with thousands of different combinations, none of them work...
Then, the new xaml :
<ControlTemplate x:Key="CheckboxImageTemplate" TargetType="Controls:ImageCheckbox">
<Image x:Name="imgForTemplate" MinWidth="100" Source="{Binding RelativeSource={RelativeSource TemplatedParent},Path=CheckedImagePath, Converter={StaticResource stringToImageConverter}}">
<!--
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="imgForTemplate" Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="{Binding RelativeSource={RelativeSource TemplatedParent},Path=CheckedImagePath, Converter={StaticResource stringToImageConverter}}" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="imgForTemplate" Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="{Binding RelativeSource={RelativeSource TemplatedParent},Path=UnCheckedImagePath, Converter={StaticResource stringToImageConverter}}" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>-->
</Image>
</ControlTemplate>
<StackPanel x:Name="LayoutRoot" Background="{StaticResource PhoneForegroundBrush}" Orientation="Horizontal">
<Controls:ImageCheckbox CheckedImagePath="treble_checked.png" UnCheckedImagePath="treble_unchecked.png" Height="72" HorizontalAlignment="Left" VerticalAlignment="Top" Template="{StaticResource CheckboxImageTemplate}" Margin="0,0,10,0" >
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<GalaSoft_MvvmLight_Command:EventToCommand CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Command="{Binding TreblePressedCommand}"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</Controls:ImageCheckbox>
</StackPanel>
I've tried to make it all work at first, but I don't seem to even get the first Source property of the image to load. The commented part (VisualStateManager states) doesn't work either, but i think it must be the same problem.. in this case I'd need a converter to return an Uri instead of a BitmapImage, because UriSource is of type Uri, and Source is of type Image.
I'm getting errors in the converter, where I can't load the images (always falling into the image_imageFailed event). I've set the images as resources in the assembly... what am i doing wrong?? this is driving me crazy!!!!
[EDIT] : I've tried doing as suggested, and changed the dependency property to Uri, but I can't get it to work
If i say
<Controls:ImageCheckbox CheckedImagePath="Images/treble_checked.png" UnCheckedImagePath="Images/treble_unchecked.png" Height="72" HorizontalAlignment="Left" VerticalAlignment="Top" Template="{StaticResource CheckboxImageTemplate}" Margin="0,0,10,0" >
and in the template's VisualState :
<BitmapImage UriSource="{Binding Path=UnCheckedImagePath, RelativeSource={RelativeSource TemplatedParent}}" />
it tells me that the xaml isn't valid and get an error. If i use TemplateBinding like this :
<BitmapImage UriSource="{TemplateBinding UnCheckedImagePath}" />
it doesn't complain, but the image doesn't load (appear blank). I think i'm getting close, but still haven't found the solution...
[EDIT 2] : last try...
usage :
<StackPanel x:Name="LayoutRoot" Background="{StaticResource PhoneForegroundBrush}" Orientation="Horizontal">
<Controls:ImageCheckbox Style="{StaticResource TheImageCheckboxStyle}" CheckedImagePath="Images/treble_checked.png" UnCheckedImagePath="Images/treble_unchecked.png" Height="72" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,10,0" >
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<GalaSoft_MvvmLight_Command:EventToCommand CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Command="{Binding TreblePressedCommand}"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</Controls:ImageCheckbox>
</StackPanel>
style (trying to copy what you pasted and removing what i thought are unnecessary parts)
<UserControl.Resources>
<Style x:Key="TheImageCheckboxStyle" TargetType="Controls:ImageCheckbox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Source">
<!-- Magic! -->
<DiscreteObjectKeyFrame KeyTime="0"
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CheckedImagePath}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Source">
<!-- Magic! -->
<DiscreteObjectKeyFrame KeyTime="0"
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=UnCheckedImagePath}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Margin="{StaticResource PhoneTouchTargetLargeOverhang}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border x:Name="CheckBackground"
Width="32"
Height="32"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding Background}"
BorderThickness="{StaticResource PhoneBorderThickness}"
IsHitTestVisible="False" />
<Rectangle x:Name="IndeterminateMark"
Grid.Row="0"
Width="16"
Height="16"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{StaticResource PhoneRadioCheckBoxCheckBrush}"
IsHitTestVisible="False"
Visibility="Collapsed" />
<!-- Magic! Default to UnCheckedImagePath -->
<Image x:Name="CheckMark"
Width="24"
Height="18"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsHitTestVisible="False"
Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=UnCheckedImagePath}"
Stretch="Fill"
Visibility="Collapsed" />
<ContentControl x:Name="ContentContainer"
Grid.Column="1"
Margin="12,0,0,0"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Have you considered changing the type of CheckedImagePath to Uri, and just binding directly to that, instead of creating a BitmapImage ?
As I see it, your code is vastly overcomplicating a simple binding.
Edit: Here's how I would do it (working example)
Use Example
<local:ImageCheckBox HorizontalAlignment="Left"
VerticalAlignment="Top"
CheckedImagePath="CheckedImage.png"
Content="CheckBox"
UnCheckedImagePath="UnCheckedImage.png" />
C#
public partial class ImageCheckBox // NameSpace: MyControls
{
public ImageCheckBox()
{
InitializeComponent();
}
public const string CheckedImagePathPropertyName = "CheckedImagePath";
public Uri CheckedImagePath
{
get
{
return (Uri)GetValue(CheckedImagePathProperty);
}
set
{
SetValue(CheckedImagePathProperty, value);
}
}
public static readonly DependencyProperty CheckedImagePathProperty =
DependencyProperty.Register(CheckedImagePathPropertyName,
typeof(Uri), typeof(ImageCheckBox), new PropertyMetadata(null));
public const string UnCheckedImagePathPropertyName = "UnCheckedImagePath";
public Uri UnCheckedImagePath
{
get
{
return (Uri)GetValue(UnCheckedImagePathProperty);
}
set
{
SetValue(UnCheckedImagePathProperty, value);
}
}
public static readonly DependencyProperty UnCheckedImagePathProperty =
DependencyProperty.Register(UnCheckedImagePathPropertyName,
typeof(Uri), typeof(ImageCheckBox), new PropertyMetadata(null));
}
XAML (Look for "Magic!" for the relevant parts)
<CheckBox x:Class="MyControls.ImageCheckBox"
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:l="clr-namespace:WindowsPhoneApplication1"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="480"
d:DesignWidth="480"
mc:Ignorable="d">
<CheckBox.Resources>
<Style x:Key="PhoneButtonBase"
TargetType="ButtonBase">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}" />
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}" />
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}" />
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}" />
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}" />
<Setter Property="Padding" Value="10,3,10,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ButtonBase">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneBackgroundBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneForegroundBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneForegroundBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="Transparent" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground"
Margin="{StaticResource PhoneTouchTargetOverhang}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="0">
<ContentControl x:Name="ContentContainer"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PhoneRadioButtonCheckBoxBase"
BasedOn="{StaticResource PhoneButtonBase}"
TargetType="ToggleButton">
<Setter Property="Background" Value="{StaticResource PhoneRadioCheckBoxBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource PhoneRadioCheckBoxBrush}" />
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}" />
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="0" />
</Style>
</CheckBox.Resources>
<CheckBox.Style>
<Style BasedOn="{StaticResource PhoneRadioButtonCheckBoxBase}"
TargetType="l:ImageCheckBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckBackground"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneRadioCheckBoxPressedBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneRadioCheckBoxPressedBorderBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneRadioCheckBoxCheckBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateMark"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneRadioCheckBoxCheckBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckBackground"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneRadioCheckBoxDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneRadioCheckBoxCheckDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateMark"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneRadioCheckBoxCheckDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource PhoneDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Source">
<!-- Magic! -->
<DiscreteObjectKeyFrame KeyTime="0"
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CheckedImagePath}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckMark"
Storyboard.TargetProperty="Source">
<!-- Magic! -->
<DiscreteObjectKeyFrame KeyTime="0"
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=UnCheckedImagePath}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="IndeterminateMark"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Margin="{StaticResource PhoneTouchTargetLargeOverhang}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border x:Name="CheckBackground"
Width="32"
Height="32"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding Background}"
BorderThickness="{StaticResource PhoneBorderThickness}"
IsHitTestVisible="False" />
<Rectangle x:Name="IndeterminateMark"
Grid.Row="0"
Width="16"
Height="16"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{StaticResource PhoneRadioCheckBoxCheckBrush}"
IsHitTestVisible="False"
Visibility="Collapsed" />
<!-- Magic! Default to UnCheckedImagePath -->
<Image x:Name="CheckMark"
Width="24"
Height="18"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsHitTestVisible="False"
Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=UnCheckedImagePath}"
Stretch="Fill"
Visibility="Collapsed" />
<ContentControl x:Name="ContentContainer"
Grid.Column="1"
Margin="12,0,0,0"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>