UWP : Worries with itemtemplateselector with GridView - xaml

I have a problem on an UWP project I'm currently working on :
I have a viewmodel like this :
public class HomePageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<WidgetViewModel> Widgets { get; } = new ObservableCollection<WidgetViewModel>();
public HomePageViewModel()
{
}
public void OnNotifyPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
And the WidgetViewModel is defined like this :
public class WidgetViewModel : INotifyPropertyChanged
{
private string group;
public string Group
{
get=>group;
set
{
group=value;
OnNotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<ItemViewModel> Items { get; } = new ObservableCollection<ItemViewModel>();
public WidgetPageViewModel()
{
}
public void OnNotifyPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
And my ItemViewModel is defined like this :
public class ItemViewModel : INotifyPropertyChanged
{
private string name;
public event PropertyChangedEventHandler PropertyChanged;
public string Name
{
get=>name;
set
{
name = value;
OnNotifyPropertyChanged();
}
}
public ItemViewModel()
{
}
public void OnNotifyPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I have produced this xaml :
<Page x:Class="Project.TestPage"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="Project"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid>
<Grid.Resources>
<CollectionViewSource x:Name="TestSource"
IsSourceGrouped="True"
Source="{Binding Widgets}" />
<local:ItemTemplateSelector x:Key="ItemTemplateSelector">
<local:ItemTemplateSelector.WidgetTemplate>
<DataTemplate>
<local:TestItemsControl ItemTemplateSelector="{StaticResource ItemTemplateSelector}"
ItemsSource="{Binding Items}">
<local:TestItemsControl.ItemContainerStyle>
<Style TargetType="local:TestItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</local:TestItemsControl.ItemContainerStyle>
</local:TestItemsControl>
</DataTemplate>
</local:ItemTemplateSelector.WidgetTemplate>
<local:ItemTemplateSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</local:ItemTemplateSelector.ItemTemplate>
</local:ItemTemplateSelector>
<x:String x:Key="ChevronGlyph"></x:String>
<Style x:Key="TextButtonStyle" TargetType="ButtonBase">
<Setter Property="MinWidth" Value="0" />
<Setter Property="MinHeight" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ButtonBase">
<Grid Background="Transparent">
<ContentPresenter x:Name="Text" Content="{TemplateBinding Content}" />
<Rectangle x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Opacity="0"
Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
StrokeDashArray="1,1"
StrokeDashOffset="1.5"
StrokeEndLineCap="Square" />
<Rectangle x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Opacity="0"
Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
StrokeDashArray="1,1"
StrokeDashOffset="0.5"
StrokeEndLineCap="Square" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="FocusVisualWhite"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
<DoubleAnimation Storyboard.TargetName="FocusVisualBlack"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked" />
<VisualState x:Name="Unchecked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationSecondaryForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TextPrimaryButtonStyle"
BasedOn="{StaticResource TextButtonStyle}"
TargetType="ButtonBase">
<Setter Property="Foreground" Value="{StaticResource ApplicationHeaderForegroundThemeBrush}" />
</Style>
<Style x:Key="GroupHeaderTextStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}" />
<Setter Property="TextTrimming" Value="WordEllipsis" />
<Setter Property="TextWrapping" Value="NoWrap" />
<Setter Property="Typography.StylisticSet20" Value="True" />
<Setter Property="Typography.DiscretionaryLigatures" Value="True" />
<Setter Property="Typography.CaseSensitiveForms" Value="True" />
<Setter Property="FontSize" Value="26.667" />
<Setter Property="LineStackingStrategy" Value="BlockLineHeight" />
<Setter Property="FontWeight" Value="Light" />
<Setter Property="LineHeight" Value="30" />
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="-1" Y="6" />
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<GridView Grid.Row="1"
Padding="116,137,40,46"
IsItemClickEnabled="False"
ItemTemplateSelector="{StaticResource ItemTemplateSelector}"
ItemsSource="{Binding Source={StaticResource TestSource}}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollMode="Disabled">
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Button AutomationProperties.Name="Group Title" Style="{StaticResource TextPrimaryButtonStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="3,-7,10,10"
Style="{StaticResource GroupHeaderTextStyle}"
Text="{Binding Key}" />
<TextBlock Margin="0,-7,0,10"
FontFamily="Segoe UI Symbol"
Style="{StaticResource GroupHeaderTextStyle}"
Text="{StaticResource ChevronGlyph}" />
</StackPanel>
</Button>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Margin="0,0,80,0"
ItemHeight="200"
ItemWidth="200"
Orientation="Vertical" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</Grid>
</Page>
The ItemTemplateSelector is defined like this :
public sealed class ItemTemplateSelector
: DataTemplateSelector
{
public DataTemplate WidgetTemplate{get;set;}
public DataTemplate ItemTemplate{get;set;}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
protected override DataTemplate SelectTemplateCore(object item)
{
if(item is ItemViewModel)
return ItemTemplate;
if(item is WidgetViewModel)
return WidgetTemplate;
return null;
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if(item is ItemViewModel)
return ItemTemplate;
if(item is WidgetViewModel)
return WidgetTemplate;
return null;
}
}
}
And the TestItemsControl is :
public class TestItemsControl : ItemsControl
{
public TestItemsControl()
{
DefaultStyleKey = typeof(TestItemsControl);
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is TestItem;
}
protected override DependencyObject GetContainerForItemOverride()
{
return new TestItem();
}
}
And TestItem is basically :
public class TestItem : ContentControl
{
public TestItem()
{
DefaultStyleKey = typeof(TestItem);
}
}
And the style for them :
<Style TargetType="local:TestItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TestItem">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStyle="{TemplateBinding FontStyle}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:TestItemsControl">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
<Setter Property="BorderBrush" Value="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
<Setter Property="Background" Value="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VariableSizedWrapGrid />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TestItemsControl">
<Grid x:Name="PART_Root">
<Rectangle x:Name="PointerOverRect"
Margin="-2"
Fill="#DE000000"
Opacity="0" />
<Border x:Name="PART_Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Margin="{TemplateBinding Padding}">
<ItemsPresenter />
</Grid>
</Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PointerOverRect"
Storyboard.TargetProperty="Opacity"
To="0.28"
Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerPressed" />
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PART_Border"
Storyboard.TargetProperty="Opacity"
To="0.3"
Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And finally how I create the items :
public class TestPage : Page
{
public TestPage()
{
InitializeComponent();
var vm = new HomePageViewModel();
DataContext = vm;
var widget = new WidgetViewModel();
widget.Add(new ItemViewModel
{
Name = "Users"
});
widget.Add(new ItemViewModel
{
Name = "16"
});
vm.Widgets.Add(widget);
}
}
I have two problems with that :(
The first problem is : The ItemTemplate is set but it not display the name of the item but this text :
"Project.ItemViewModel" and I can't understand why
The second problem is the child doesn't fill its parent container.
To explain what I'm trying to achieve, the basic idea is to have a component which swap its content after a delay.
So here I have a GridView with items and each item could have many contents.
That's why I used a TestItemsControl. It's easier to manage swapping content with it...
Any Ideas?
EDIT : I made some steps. I have one remaining problem. It is :
The DataTemplate is set into the container but it is not applied.
When I break point on DataTemplateSelector, I see my TestItemContainer and the DataTemplateSelector is set in it, but the item always display a textblock with the text "XXXX.XXXX.ViewModel"
And with the datatemplate I need to show the property 'Name' of the ViewModel
Thanks for any help

Related

UWP-CPP/Winrt Make a Line Control of the ListViewItem Data Template only visible when selected

I am planning to show a list of objects using ListView. According to the design when an Item is selected a blue line should appear in the content of the Item. I have written the below code and tried to change the visibility to visible (search for ----------Setting visibility Here in second code snippet) in Style of the ListViewItem defined as below. But doing so its throwing error. And I am not able to access the BlueLine object in the code behind when an ListViewItem is selected. Can you please help how this can be achieved. TIA
<ListView
x:Name="ObjectList"
ItemsSource="{x:Bind ObjectViewModel.Objects}"
SelectionChanged="ListViewButtonClick"
MaxWidth ="{StaticResource ColumnMaximumWidth}"
VerticalAlignment = "Center"
HorizontalContentAlignment = "Stretch"
ScrollViewer.HorizontalScrollBarVisibility ="Disabled"
SelectionMode ="Single" />
<ListView.Resources>
<SolidColorBrush x:Key="ListViewItemBackgroundSelected" Color="Green" />
<SolidColorBrush x:Key="ListViewItemBackgroundSelectedPointerOver" Color="Green" />
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,0,30" />
</Style>
</ListView.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="local:ObjectModel">
<Grid MinHeight="66" CornerRadius="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Line
x:Name="BlueLine"
Stroke="Blue"
StrokeThickness="4"
Visibility="Collapsed"
X1="0"
X2="0"
Y1="0"
Y2="60" />
<FontIcon
Grid.Column="1"
FontSize="17"
Glyph=""
Style="{StaticResource FontIconStyle1}" />
<TextBlock
Grid.Column="2"
Style="{StaticResource AddBluetoothLabelTextStyle}"
Text="{x:Bind ObjectName, Mode=OneWay}" />
</Grid>
</ItemsControl.ItemTemplate>
</ListView>
<Style TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="{ThemeResource ListViewItemBackground}" />
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}" />
<Setter Property="TabNavigation" Value="Local" />
<Setter Property="IsHoldingEnabled" Value="True" />
<Setter Property="Padding" Value="12,0,12,0" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}" />
<Setter Property="AllowDrop" Value="False" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter
x:Name="Root"
Margin="0,0,0,30"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
CheckBrush="{ThemeResource ListViewItemCheckBrush}"
CheckMode="{ThemeResource ListViewItemCheckMode}"
ContentMargin="{TemplateBinding Padding}"
ContentTransitions="{TemplateBinding ContentTransitions}"
Control.IsTemplateFocusTarget="True"
CornerRadius="4"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
DragBackground="{ThemeResource ListViewItemDragBackground}"
DragForeground="{ThemeResource ListViewItemDragForeground}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}"
PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
PressedBackground="{ThemeResource ListViewItemBackgroundPressed}"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
RevealBackground="{ThemeResource ListViewItemRevealBackground}"
RevealBorderBrush="{ThemeResource ListViewItemRevealBorderBrush}"
RevealBorderThickness="{ThemeResource ListViewItemRevealBorderThemeThickness}"
SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}"
SelectedForeground="{ThemeResource ListViewItemForegroundSelected}"
SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}"
SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}"
SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected"> ----------Setting visibility Here
<VisualState.Setters>
<Setter Target="BlueLine.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="PointerOver" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOverPressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PressedSelected">
<VisualState.Setters>
<Setter Target="Root.(RevealBrush.State)" Value="Pressed" />
<Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DisabledStates">
<VisualState x:Name="Enabled" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="Root.RevealBorderThickness" Value="0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
There is an approach could be used to access the BlueLine object in code behind when a ListViewItem is selected by using VisualTreeHelper class.
Please check the following code:
Add headers and namespaces:
#include <winrt/Windows.UI.Xaml.Shapes.h>
#include <winrt/Windows.UI.Xaml.Media.h>
using namespace winrt::Windows::UI::Xaml::Shapes;
using namespace Windows::UI::Xaml::Media;
Add a private member in .h file:
private:
Line previousLine{ nullptr };
Access the BlueLine object in code behind:
void winrt::ListViewStyle::implementation::MainPage::ObjectList_SelectionChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::SelectionChangedEventArgs const& e)
{
if (previousLine != nullptr)
{
previousLine.Visibility(Visibility::Collapsed);
}
auto selectedItemContainer = ObjectList().ContainerFromItem(ObjectList().SelectedItem());
auto presenter = VisualTreeHelper::GetChild(selectedItemContainer.try_as<DependencyObject>(), 0);
auto grid = VisualTreeHelper::GetChild(presenter, 0);
auto line = VisualTreeHelper::GetChild(grid, 0).try_as<Line>();
line.Visibility(Visibility::Visible);
previousLine = line;
}

Non clickable checkbox when applying style

I have made plenty of styles and they all work (so the issue is not with the ResourceDictionary or binding to the style), but when i try to use this style for a checkbox it goes into a state where the user can't interact with it.
I'm attempting to set a style on a standard CheckBox:
<CheckBox Content="Some Cool Checkbox" Style="{StaticResource MaterialDesignCheckBox}" />
This is the style I'm trying to apply:
<Style x:Key="MaterialDesignCheckBox" TargetType="CheckBox">
<Setter Property="Background" Value="{ThemeResource CheckBoxBackgroundUnchecked}" />
<Setter Property="Foreground" Value="{ThemeResource CheckBoxForegroundUnchecked}" />
<Setter Property="BorderBrush" Value="{ThemeResource CheckBoxBorderBrushUnchecked}" />
<Setter Property="Padding" Value="8,5,0,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="32" />
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Grid
x:Name="RootGrid"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Viewbox
Width="25"
Height="25"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
FlowDirection="LeftToRight">
<Canvas Width="25" Height="25">
<Path
x:Name="Graphic"
Data="M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M19,5V19H5V5H19Z"
Fill="{ThemeResource MaterialDesignCheckBoxOff}" />
<Ellipse
x:Name="InteractionEllipse"
Canvas.Left="12"
Canvas.Top="12"
Width="0"
Height="0"
Fill="{TemplateBinding Foreground}"
IsHitTestVisible="False"
Opacity="0"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
</Viewbox>
<ContentPresenter
x:Name="ContentPresenter"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
TextWrapping="Wrap" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
When applying the style the checkbox becomes unclickable, but with the correct look:
So in short i need help with figuring out how to keep the look but also make it clickable.
Non clickable checkbox when applying style
For add the clickable status, you need to specify the visual behavior for Checkbox. For example,
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="CheckGlyph.Opacity" Value="1"/>
</VisualState.Setters>
<!-- This Storyboard is equivalent to the Setter. -->
<!--<Storyboard>
<DoubleAnimation Duration="0" To="1"
Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Opacity"/>
</Storyboard>-->
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate">
<VisualState.Setters>
<Setter Target="IndeterminateGlyph.Opacity" Value="1"/>
</VisualState.Setters>
<!-- This Storyboard is equivalent to the Setter. -->
<!--<Storyboard>
<DoubleAnimation Duration="0" To="1"
Storyboard.TargetName="IndeterminateGlyph" Storyboard.TargetProperty="Opacity"/>
</Storyboard>-->
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
For detail tutorial please refer Specify the visual behavior of a control.
Solved the issue by doing this:
<Style x:Key="MaterialDesignCheckBox" TargetType="CheckBox">
<Setter Property="Background" Value="{ThemeResource CheckBoxBackgroundUnchecked}" />
<Setter Property="Foreground" Value="{ThemeResource CheckBoxForegroundUnchecked}" />
<Setter Property="BorderBrush" Value="{ThemeResource CheckBoxBorderBrushUnchecked}" />
<Setter Property="Padding" Value="8,5,0,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="32" />
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle
x:Name="NormalRectangle"
Grid.Column="0"
Width="20"
Height="20"
Fill="Transparent"
RadiusX="2"
RadiusY="2"
Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
UseLayoutRounding="False" />
<Path
x:Name="CheckGlyph"
Grid.Column="0"
Width="16"
Height="14"
Fill="{ThemeResource MaterialDesignCheckBoxOff}"
Opacity="0"
Stretch="Fill"
Stroke="{StaticResource MaterialDesignCheckBoxOff}"
StrokeThickness="1.5">
<Path.Data>
<GeometryGroup>
<LineGeometry StartPoint="0,0" EndPoint="100,100" />
<LineGeometry StartPoint="100,0" EndPoint="0,100" />
</GeometryGroup>
</Path.Data>
</Path>
<Ellipse
x:Name="IndeterminateGlyph"
Grid.Column="1"
Width="8"
Height="8"
Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
Opacity="0"
UseLayoutRounding="False" />
<ContentPresenter
x:Name="ContentPresenter"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="CheckGlyph.Opacity" Value="1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate">
<VisualState.Setters>
<Setter Target="IndeterminateGlyph.Opacity" Value="1" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

UWP ListView - DragOver not called anymore

I'm facing an issue that I can't solve. I have a ListView and I need to customize item style when the user drag an object over the list view item. Due to the complexity of my states, I don't want to keep the ListViewItemPresenter of the extended ListViewItem style. So when i remove that presenter and define my own style (basically a classic content presenter + overlay + underlay + VisualStateGroups to define animations), I don't recieve the DragOver and Drop event anymore on my list item objects. I don't understand why ? If i keep the default item container style it works fine... What did i miss?
Let me go a bit further with some code. Here is my List view that define ItemTemplate and ItemContainerStyle :
<ListView x:Name="notebookListView"
ItemsSource="{x:Bind NoteBookItems}"
ItemTemplate="{StaticResource NotebookItemListViewTemplate}"
ItemContainerStyle="{StaticResource notebookItemContainerStyle}"
IsItemClickEnabled="True"
SelectionMode="Single"
AllowDrop="True" CanReorderItems="False" CanDragItems="True"
DragItemsStarting="NotebookListView_DragItemsStarting"
DragItemsCompleted="NotebookListView_DragItemsCompleted"
ItemClick="NotebookItem_Click" />
Here is the item template that define the DragOver and Drop method:
<DataTemplate x:Name="NotebookItemListViewTemplate" x:DataType="model:NotebookItem">
<Grid x:Name="notebook" HorizontalAlignment="Left" Height="48" Width="320"
AllowDrop="True"
DragOver="DragOverNotebookItem"
Drop="DropInNotebookItem">
[...]
</Grid>
</DataTemplate>
And finaly my extended item container style:
<Style x:Key="notebookItemContainerStyle" TargetType="ListViewItem">
<!-- all default setter properties ... -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<!-- Here is my customization with VisualState to catch PointerOver and other events above my list items -->
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="overlay" Duration="0" To="{StaticResource ColorUIBlackAlpha04}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="overlay" Duration="0" To="{StaticResource ColorUIBlackAlpha12}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
<VisualState x:Name="PressedSelected">
<Storyboard>
<ColorAnimation Storyboard.TargetName="overlay" Duration="0" To="{StaticResource ColorUIBlackAlpha12}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimation Storyboard.TargetName="overlay" Duration="0" To="Transparent" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- and a Grid that contains the definition of the item content -->
<Grid>
<Rectangle x:Name="underlay" Stroke="Transparent" Fill="Transparent" Margin="0" />
<ContentPresenter Margin="{TemplateBinding Padding}"
Background="Transparent"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Rectangle x:Name="overlay" Stroke="Transparent" Fill="Transparent" Margin="0" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
With that code, the DragOver event of my item is never triggered. But if i use the default item container style with the default ListViewItemPresenter it works fine. I don't understand why... Could anyone help me to understand what happens ?
Here is the default list view item container style, with the ListViewItemPresenter instead of my custo:
<Style x:Key="notebookItemContainerStyle" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="Background" Value="{ThemeResource ListViewItemBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="12,0,12,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
<Setter Property="AllowDrop" Value="True"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="FocusVisualMargin" Value="0"/>
<Setter Property="FocusVisualPrimaryBrush" Value="{ThemeResource ListViewItemFocusVisualPrimaryBrush}"/>
<Setter Property="FocusVisualPrimaryThickness" Value="2"/>
<Setter Property="FocusVisualSecondaryBrush" Value="{ThemeResource ListViewItemFocusVisualSecondaryBrush}"/>
<Setter Property="FocusVisualSecondaryThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter CheckBrush="{ThemeResource ListViewItemCheckBrush}"
ContentMargin="{TemplateBinding Padding}"
CheckMode="{ThemeResource ListViewItemCheckMode}"
ContentTransitions="{TemplateBinding ContentTransitions}"
CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
DragForeground="{ThemeResource ListViewItemDragForeground}"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
DragBackground="{ThemeResource ListViewItemDragBackground}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Control.IsTemplateFocusTarget="True"
PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
PressedBackground="{StaticResource UIBlackAlpha12}"
PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
PointerOverBackground="{StaticResource UIBlackAlpha04}"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
SelectedPressedBackground="Transparent"
SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}"
SelectedForeground="{ThemeResource ListViewItemForegroundSelected}"
SelectedPointerOverBackground="Transparent"
SelectedBackground="Transparent"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I could reproduce your issue, but I don't know the reason that caused this issue. I will continue to study this issue. Currently, there is a workaround for you. I found you want to modify the color of underlay overlay Rectangle. You could realize this in the code behind rather than in xaml with Visualtreehelper.
private void MYListview_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
StackPanel test = MyFindListViewChildByName(MYListview.ContainerFromItem(MYListview.SelectedItem), "MyTest") as StackPanel;
test.Background = new SolidColorBrush(Colors.White);
}
public static DependencyObject MyFindListViewChildByName(DependencyObject parant, string ControlName)
{
int count = VisualTreeHelper.GetChildrenCount(parant);
for (int i = 0; i < count; i++)
{
var MyChild = VisualTreeHelper.GetChild(parant, i);
if (MyChild is FrameworkElement && ((FrameworkElement)MyChild).Name == ControlName)
return MyChild;
var FindResult = MyFindListViewChildByName(MyChild, ControlName);
if (FindResult != null)
return FindResult;
}
return null;
}
You could use VisualTreeHelper to get underlay overlay Rectangle instance then create animation for them. You could invoke those animation manually in ListViewItem event handler that match xaml VisualStateGroup.

Keep PointerOver from changing text color of Checked button

I am having issue trying to have a set of radio buttons behave as buttons, and my goal is to have the text color of the buttons change on hover, and to have it go back to original color and be bolded on click. I am implementing recomendations on a previous similar question here but I seem to be doing something wrong because I am not getting the desired behavior. When I hover over the buttons the PointerOver is still changing the text color of a "Checked" button
<Page.Resources>
<Style x:Key="RadioButtonStyle" TargetType="RadioButton">
<Setter Property="Background" Value="{ThemeResource RadioButtonBackground}"/>
<Setter Property="Foreground" Value="{ThemeResource RadioButtonForeground}"/>
<Setter Property="BorderBrush" Value="{ThemeResource RadioButtonBorderBrush}"/>
<Setter Property="Padding" Value="8,6,0,0"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid x:Name="RootGrid" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="Purple" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
</VisualState>
<VisualState x:Name="Disabled">
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="FocusContentPresenter.FontWeight" Value="Bold" />
<Setter Target="ContentPresenter.FontWeight" Value="Bold" />
<Setter Target="FocusContentPresenter.(UIElement.Opacity)" Value="1" />
<Setter Target="ContentPresenter.(UIElement.Opacity)" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" Grid.Column="1" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" TextWrapping="Wrap" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter x:Name="FocusContentPresenter" Opacity="0" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<RadioButton Content="RadioButton" GroupName="Menu" HorizontalAlignment="Left" Margin="10,165,0,0" VerticalAlignment="Top" Style="{StaticResource RadioButtonStyle}"/>
<RadioButton Content="RadioButton" GroupName="Menu" HorizontalAlignment="Left" Margin="10,235,0,0" VerticalAlignment="Top" Style="{StaticResource RadioButtonStyle}"/>
<RadioButton Content="RadioButton" GroupName="Menu" HorizontalAlignment="Left" Margin="10,94,0,0" VerticalAlignment="Top" Style="{StaticResource RadioButtonStyle}" />
</Grid>
I think you are almost there except some minor padding issues.
<Style x:Key="RadioButtonStyle" TargetType="RadioButton">
<Setter Property="Background" Value="{ThemeResource RadioButtonBackground}" />
<Setter Property="Foreground" Value="{ThemeResource RadioButtonForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource RadioButtonBorderBrush}" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="FocusVisualMargin" Value="-7,-3,-7,-3" />
<Setter Property="Padding" Value="16,12" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid x:Name="RootGrid" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="ContentPresenter.Foreground" Value="Purple" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
</VisualState>
<VisualState x:Name="Disabled">
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="FocusContentPresenter.FontWeight" Value="Bold" />
<Setter Target="ContentPresenter.FontWeight" Value="Bold" />
<Setter Target="FocusContentPresenter.(UIElement.Opacity)" Value="1" />
<Setter Target="ContentPresenter.(UIElement.Opacity)" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" TextWrapping="Wrap" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" />
<ContentPresenter x:Name="FocusContentPresenter" Opacity="0" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Custom template for radio button and using Visual State

This is a custom style that i am using for a radio button.The concept is to flip the foreground and background color between checked and unchecked state. Everything works fine until i move mouse over a checked button and move it out.
The foreground switches back to Primary Color.
TO Clarify this it what i think is happening.
When the button is clicked, the checked state gets active.
When you move the pointer over, PointerOver state gets active and changes the foreground to WhiteTextAndIcons color.
When the pointer moves out the foreground return to default which is PrimaryColor, hence it matches the background.
What i need is , if the state is checked then the foreground should not default back, when pointer is moved in or out. Is this possible via style?
This is the workaround i am using, but i want to know what am i doing wrong here.
Workaround:
private void MainPage_PointerExited(object sender, PointerRoutedEventArgs e)
{
if(sender is RadioButton)
{
var radio = sender as RadioButton;
if(radio.IsChecked.HasValue && radio.IsChecked.Value)
{
radio.IsChecked = false;
radio.IsChecked = true;
}
}
}
Color and Custom Template.
<Color x:Key="DarkPrimaryColor">#FF1664A7</Color>
<Color x:Key="PrimaryColor">#FF0078D7</Color>
<Color x:Key="LightPrimaryColor">#FF2488D8</Color>
<Color x:Key="WhiteTextAndIcons">#FFFFFFFF</Color>
<SolidColorBrush x:Key="NavButtonPressedBackgroundBrush" Color="{ThemeResource PrimaryColor}" />
<SolidColorBrush x:Key="NavButtonHoverBackgroundBrush" Color="{ThemeResource LightPrimaryColor}" />
<SolidColorBrush x:Key="NavButtonCheckedBackgroundBrush" Color="{ThemeResource PrimaryColor}" />
<SolidColorBrush x:Key="NavButtonCheckedPressedBackgroundBrush" Color="{ThemeResource DarkPrimaryColor}" />
<SolidColorBrush x:Key="NavButtonCheckedHoverBackgroundBrush" Color="{ThemeResource LightPrimaryColor}" />
<SolidColorBrush x:Key="NavButtonCheckedForegroundBrush" Color="{ThemeResource WhiteTextAndIcons}" />
<SolidColorBrush x:Key="NavButtonForegroundBrush" Color="{ThemeResource PrimaryColor}" />
<Style TargetType="RadioButton" x:Key="SplitViewRadioButtonWithWhiteBGStyle">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{ThemeResource NavButtonForegroundBrush}" />
<Setter Property="Padding" Value="1,4,0,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="HoverBackground.Visibility" Value="Visible"/>
<Setter Target="CheckedHoverBackground.Visibility" Value="Visible"/>
<Setter Target="NixonGlyph.(ContentPresenter.Foreground)" Value="{StaticResource NavButtonCheckedForegroundBrush}"/>
<Setter Target="ContentPresenter.Foreground" Value="{StaticResource NavButtonCheckedForegroundBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="PressedBackground.Visibility" Value="Visible"/>
<Setter Target="CheckedPressedBackground.Visibility" Value="Visible"/>
<Setter Target="NixonGlyph.(ContentPresenter.Foreground)" Value="{StaticResource NavButtonCheckedForegroundBrush}"/>
<Setter Target="ContentPresenter.Foreground" Value="{StaticResource NavButtonCheckedForegroundBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="NixonGlyph.(ContentPresenter.Foreground)" Value="{ThemeResource RadioButtonContentDisabledForegroundThemeBrush}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource RadioButtonContentDisabledForegroundThemeBrush}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="CheckedBackground.Visibility" Value="Visible"/>
<Setter Target="NixonGlyph.(ContentPresenter.Foreground)" Value="{StaticResource NavButtonCheckedForegroundBrush}"/>
<Setter Target="ContentPresenter.Foreground" Value="{StaticResource NavButtonCheckedForegroundBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualWhite" Storyboard.TargetProperty="Opacity" To="1" />
<DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualBlack" Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="Rectangle" x:Name="FocusVisual">
<Setter Property="Opacity" Value="0" />
<Setter Property="StrokeDashArray" Value="1,1" />
<Setter Property="StrokeEndLineCap" Value="Square" />
</Style>
</Grid.Resources>
<!-- background -->
<Grid x:Name="NotCheckedBackground" Grid.ColumnSpan="4">
<Rectangle x:Name="PressedBackground" Visibility="Collapsed" Fill="{StaticResource NavButtonPressedBackgroundBrush}"/>
<Rectangle x:Name="HoverBackground" Visibility="Collapsed" Fill="{StaticResource NavButtonHoverBackgroundBrush}"/>
</Grid>
<Grid x:Name="CheckedBackground" Grid.ColumnSpan="4" Visibility="Collapsed" Background="{StaticResource NavButtonCheckedBackgroundBrush}">
<Rectangle x:Name="CheckedPressedBackground" Visibility="Collapsed" Fill="{StaticResource NavButtonCheckedPressedBackgroundBrush}"/>
<Rectangle x:Name="CheckedHoverBackground" Visibility="Collapsed" Fill="{StaticResource NavButtonCheckedHoverBackgroundBrush}"/>
</Grid>
<!-- focus -->
<Rectangle x:Name="FocusVisualWhite" Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashOffset="1.5" Style="{StaticResource FocusVisual}" />
<Rectangle x:Name="FocusVisualBlack" Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}" StrokeDashOffset="0.5" Style="{StaticResource FocusVisual}" />
<!-- glyph -->
<ContentPresenter x:Name="NixonGlyph" Content="{TemplateBinding Tag}" />
<!-- text -->
<ContentPresenter x:Name="ContentPresenter"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>