CollectionView GridItemsLayout Change BackgroundColor of nested Item (Button) - xaml

I have a problem concerning a CollectionView with a GridItemsLayout. In my application, I have a StackLayout with a horizontal CollectionView(GridItemsLayout), which contains a Button bound to a certain category.
Whenever a button is clicked/tapped, it filters the ListView (of type Surgery) below based on the category. All of that is working fine, however, I would like to highlight the Category/Button by changing it BackgroundColor to see which category is currently used for filtering.
<CollectionView HeightRequest="70"
x:Name="categoryCollection"
ItemsSource="{Binding Categories}"
Margin="20,0,20,0"
SelectionMode="Single">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal" Span="1" HorizontalItemSpacing="5"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="0,5,0,5">
<Button x:Name="categoryButton" Text="{Binding Name}"
Command="{Binding Path=BindingContext.FilterCommand, Source={x:Reference Name=SurgeryListView}}"
CommandParameter="{Binding .}"
CornerRadius="15"
FontFamily="OpenSans" Margin="0,5,10,5"
Opacity="0.6" FontSize="16" TextTransform="None">
</Button>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<ListView x:Name="listView"
ItemsSource="{Binding Surgeries}"
RefreshCommand="{Binding LoadSurgeriesCommand}"
IsRefreshing="{Binding IsRefreshing}"
IsPullToRefreshEnabled="True"
RowHeight="70"
BackgroundColor="{StaticResource darkThemeBackground}"
ItemTemplate="{StaticResource surgeryDataTemplateSelector}">
<ListView.Behaviors>
<behaviors:EventToCommandBehavior
EventName="ItemTapped"
Command="{Binding SurgerySelectedCommand}"
EventArgsConverter="{StaticResource ItemTappedConverter}">
</behaviors:EventToCommandBehavior>
</ListView.Behaviors>
</ListView>
I tried to use VisualStates but that was not working, because tapping the button does not actually change the SelectedItem (one would need to click the surrounding/parent grid element for that). Moreover, the altered VisualState was only applied to the Grid's BackgroundColor, not to that of the actual button.
Question: How can I highlight the current Category/Button by changing its Background Color?

Since the selection is working good, remains only the ui/xaml part, if you look at the documentation about VisualStateManager, you can add the following style:
<CollectionView.Resources>
<Style TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="LightSkyBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</CollectionView.Resources>

Related

UWP-CPP/Winrt Set Corner radius of the ListViewItem when hovered/selected

I am planning to show a list of objects using ListView. According to the design the rectangle around the ListViewItem should be rounded at the corners. Have tried multiple ways to achieve the same but couldn't find a solution.
<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">
<Border
BorderBrush="Red"
BorderThickness="3"
CornerRadius="5">
<Grid MinHeight="66" CornerRadius="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<FontIcon
FontSize="17"
Glyph=""
Style="{StaticResource FontIconStyle1}" />
<TextBlock
Grid.Column="1"
Style="{StaticResource AddBluetoothLabelTextStyle}"
Text="{x:Bind ObjectName, Mode=OneWay}" />
</Grid>
</Border>
</ItemsControl.ItemTemplate>
</ListView>
As shown in the picture the corners of the selected/hovered items is not rounded. Can you please help how this can be achieved. TIA
You need to change the VisualState to set CornerRadius of ListViewItem in style of ListViewItem.
Please check the following steps:
Open generic.xaml file, find a Style whose TargetType is ListViewItem and Key is ListViewItemRevealStyle. Copy the style into your Page.Resources.
Delete the x:Key property of the style so that the style could be used in all ListViewItem in the current Page.
Find a VisualState whose name is Selected, add the following code:
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="Root.CornerRadius" Value="10" />
</VisualState.Setters>
</VisualState>
Find VisualStates whose names are PointerOver, PointerOverSelected, PointerOverPressed, PointerOverPressed, add the following code seperately:
<Setter Target="Root.CornerRadius" Value="10" /> <!--Add this code-->
Delete the ListView.ItemContainerStyle statement, which conflicts with the ListViewItem’s style.
Note, it is better if you could follow the above steps first to set corner radius in the style of ListViewItem then add other style or settings later, which could ensure settings in the style of ListViewItem work.

Segmented control Xamarin Forms customisation

I would like to create the segmented control in the image below.
What i currently have or attempted using is the library in the following link : https://github.com/1iveowl/Plugin.SegmentedControl
How ever as you can see the final result ends up being a horizontal segmented UI, which is what I do not want.
I have checked the documentation of the plugin to see if there is a way of changing the orientation and it seems that is the current limitation of the plugin
<control:SegmentedControl
x:Name="SegmentedGenderControl"
TintColor="#F2EBF9"
SelectedTextColor="#6F1AC1"
TextColor="Black"
DisabledColor="White"
BorderColor="#6F1AC1"
BorderWidth="1.0"
FontSize="Medium"
Margin="8,8,8,8">
<control:SegmentedControl.Children >
<control:SegmentedControlOption Text="Male"/>
<control:SegmentedControlOption Text="Female"/>
<control:SegmentedControlOption Text="Female"/>
</control:SegmentedControl.Children>
</control:SegmentedControl>
The second alternative that I have thought about is using a grid with 3 rows :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
</Grid>
And then manually handle the selection based on the selection. Is there a simpler or plugin that is available to the public that is not the one above that I can use ?
So I finally managed to solve this problem as suggested by an external party through the use of a collection view
See the code that follows :
<CollectionView
HeightRequest="250"
x:Name="OptionsCollectionView"
ItemsSource="{Binding SelectionOptions}"
VerticalOptions="Start"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<yummy:PancakeView
x:Name="optionPancake"
Padding="20">
<yummy:PancakeView.Border>
<yummy:Border
Color="{StaticResource CollectionViewBorderColor}"
Thickness="2" />
</yummy:PancakeView.Border>
<StackLayout
Orientation="Horizontal">
<Label
x:Name="optionLabel"
Text="{Binding Option}"
FontSize="15"
FontFamily="EuclidCircularASemibold"
TextColor="{StaticResource SubHeadingColor}"
FontAttributes="Bold" />
</StackLayout>
</yummy:PancakeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The code that follows is for styling the visual state group, when an item is selected:
<Style TargetType="yummy:PancakeView">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup>
<VisualState Name="Normal"/>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter
Property="BackgroundColor"
Value="{StaticResource FrameSelectedColor}"/>
<Setter
Property="yummy:PancakeView.Border"
Value="{yummy:BorderMarkup Color={StaticResource SelectedLabelColor}, Thickness='2'}"/>
<Setter TargetName="optionLabel"
Property="Label.TextColor"
Value="{StaticResource SelectedLabelColor}"/>
<Setter Property="CornerRadius"
Value="5"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>

How can I change visual of flyoutitem in xamarin shell on select?

I want to highlight current page by changing background color of a flyoutitem, but I also need to change text color inside a frame. My Template
<Grid ...>
<Frame CornerRadius="10"
Padding="0"
BackgroundColor="White"
Grid.Column="1">
<Label Text="{Binding Title}"
Margin="50,0,0,0"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center"
TextColor="Black"
Grid.Column="1"/>
</Frame>
</Grid>
I need to change Frame color to darker green and label text color to white whenever I navigate to a certain page. I've tried visual state manager, but it doesn't work even just with background-only. I found a solution to attach trigger on a Frame, but nothing happens
protected override void Invoke(Frame sender)
{
sender.BackgroundColor = Color.FromHex("#229904");
(sender.Content as Label).TextColor = Color.White;
}
Firstly, you need to add a custom style in your resources:
<Style x:Key="FloutItemStyle" TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="xxx"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
Then consume it in your Shell:
<Shell.ItemTemplate>
<DataTemplate >
<Grid Style="{StaticResource FloutItemStyle}">
//...
</Grid>
</DataTemplate>
</Shell.ItemTemplate>

How fadeout element in dataTemplate when mouse clicked its containter? My idea throw always exception

This code throw always exception. Is a way to get TextBox (x:Name = "MyBox") to hide (fadeout) when we click in its container (here ListViewItem)? What's wrong with my code?
<ListView x:Name="ListViewMy" IsItemClickEnabled="True" ItemsSource="{Binding list, Mode=TwoWay}" HorizontalAlignment="Left" Height="223" Margin="240,350,0,0" VerticalAlignment="Top" Width="582" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid x:Name="GridMy">
<ContentPresenter x:Name="MyContentPresenter">
<ContentPresenter.ContentTemplate>
<DataTemplate x:Key="DataTemplate">
<Grid Background="#FF25C1D1" Margin="-30,0,0,0" x:Name="GridBlue">
<TextBox x:Name="MyBox" HorizontalAlignment="Left" Margin="135,0,0,0" TextWrapping="Wrap" Text="{Binding}" VerticalAlignment="Top" Width="352" Height="81" Background="{x:Null}" BorderBrush="#FF25C1D1" FontFamily="Segoe WP Semibold" FontSize="32" FontWeight="Bold" Foreground="White"/>
</Grid>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed" >
<Storyboard>
<FadeOutThemeAnimation TargetName="MyBox" Duration="0:0:5"></FadeOutThemeAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
The problem with your code is that your animation, in the ControlTemplate for ListViewItem, should only target other elements within the ControlTemplate for ListViewItem. The DataTemplate won't work here because x:Name="MyBox" won't resolve. DataTemplates are reusable pieces of UI so Name expansion is skipped on them.
A good way to achieve your scenario is to target the animation to the ContentPresenter that is in fact part of your ControlTemplate, i.e.:
<FadeOutThemeAnimation TargetName="MyContentPresenter" Duration="0:0:5" />

Listview Disabling item click

I am developing Windows Store App, and I have such XAML code:
<Popup x:Name="Panel3" IsOpen="False" Grid.ColumnSpan="18" Grid.Column="13" Grid.Row="4" Grid.RowSpan="31">
<StackPanel>
<Rectangle Width="765" Height="10" />
<ListView x:Name="Person" Grid.ColumnSpan="18" Grid.Column="13" HorizontalAlignment="Left" Height="643" Grid.Row="4" Grid.RowSpan="31" VerticalAlignment="Top" Width="765" >
<ListView.Background>
<SolidColorBrush Color="#FF665920" Opacity="0.85"/>
</ListView.Background>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Popup>
I want to make item selection on listview disabled. So it is for view only, users cannot select/click anything inside listview. How can i make that happen? My regards...
P.S.
I added IsItemClickEnabled="False" to listview line:
<ListView x:Name="Person" Grid.ColumnSpan="18" Grid.Column="13" HorizontalAlignment="Left" Height="643" Grid.Row="4" Grid.RowSpan="31" VerticalAlignment="Top" Width="765" IsItemClickEnabled="False">
But it did not change anything, still clickable.
You need set the SelectionMode property to None to disable the item selection of a ListView:
<ListView x:Name="Person" SelectionMode="None" ... />
additionally you may still need the IsItemClickEnabled="False" depending on your needs.
I've found you need to modify the visual state of the ListViewItem along with setting the SelectionMode="None" and IsItemClickEnabled="False" if needed, as nemesv said in his answer.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<!-- here we are clearing the state behavior,
thus disabling the clickability of the ListViewItem -->
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver" />
<VisualState x:Name="Pressed" />
/VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<ContentPresenter x:Name="ListViewItemContent" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>