Style resource inheriting from parent - xaml

I've got two stack panels nested within another stackpanel, the nested stack panels both have images in which need to be the same size, so I've used a style resorce. But this means duplicating the style resources in each stack panel. As shown;
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horiztonal">
<StackPanel.Resources>
<Style TargetType="Image">
<Setter Property="Width" Value="20"/>
</Style>
</StackPanel.Resources>
<Image />
<Image />
<Image />
<Image />
</StackPanel>
<StackPanel Orientation="Horiztonal">
<StackPanel.Resources>
<Style TargetType="Image">
<Setter Property="Width" Value="20"/>
</Style>
</StackPanel.Resources>
<Image />
<Image />
<Image />
<Image />
</StackPanel>
</StackPanel>
Is there a way to set this style on my surrounding stackpanel and have the children inherit that style, or would I be looking at making a style template (as shown; https://learn.microsoft.com/en-us/dotnet/framework/wpf/controls/styling-and-templating) and applying it individually to my images?

I do not recommend inheriting style using "previous style" as the base. Instead, I would define the style explicitly as the base style as a static resource, and then apply the style to any control that needs that style (or inherit the style).
For ex:
In the User Control level, let's define the base style.
<UserControl>
<UserControl.Resources>
<!--Define StackPanel Style with a key as the base-->
<Style x:Key="ImageStyle" TargetType="{x:Type Image}">
<Setter .... />
</Style>
<!-- To apply the style above, you need to explicitly set the style using Style="{StaticResource ImageStyle}"-->
</UserControl.Resources>
</UserControl>
In the body, we can apply the style to specific Control, but in our case we want to apply to all Images inside the OuterStackPanel, therefore:
<StackPanel x:Name="OuterStackPanel">
<StackPanel.Resources>
<!-- Without specifying the key, this will apply the style to all Images inside this StackPanel including NestedStackPanels -->
<!-- Also, with BasedOn, this will inherit the style from ImageStyle defined above -->
<Style TargetType="{x:Type Image}" BasedOn="{StaticResource ImageStyle}">
<Setter .../> <!-- In Case if you want to add another setter, for ex: Width=20. Or don't add any other Setter to have the original style-->
</Style>
</StackPanel.Resources>
<StackPanel x:Name="NestedStackPanel1">
<Image />
<Image />
<Image />
<Image />
</StackPanel>
<StackPanel x:Name="NestedStackPanel2">
<Image />
<Image />
<Image />
<Image />
</StackPanel>
</StackPanel>
If you need to have different style for each nestedStackPanel, you can move the styling inside the nestedStackPanel, instead.

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.

why ButtonPressedBackgroundThemeBrush is not working for button

Whenever I press and hold the button I can see a blue color background till I release the button
I tried to reset it white by using the key ButtonPressedBackgroundThemeBrush
Here is my button code
<Button Content="Submit" BorderThickness="0" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" FontSize="21" Height="85" BorderBrush="White" Command="{Binding testCommand}" Foreground="{StaticResource Green}">
<Button.Resources>
<SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="White" />
</Button.Resources>
</Button>
But its not working for some reason.
Try defining the brush in your application resources:
<Application.Resources>
<SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="White" />
</Application.Resources>
This will change the button press background for ALL buttons however. If you want specific buttons to have different backgrounds, you'll need to edit the Button template for each. One simple way to do that is to define a style for each and set the Background to whatever you like during the IsPressed Trigger
<Button>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

Fieldset in Winrt/XAML

I need to create something in WinRT/XAML similar to an HTML fielset. http://jsfiddle.net/Sf2Vy/
Basically, I have a border and there is some text on top of the border. Where the text covers the border, I need the border to not show under the text. The background behind the border isn't a solid color so I can't just set the background color of the text. The text length is variable also.
Is there an easy way to do this?
Yeah, so, the answer is no. There is no FieldSet.
Having said that, I think you could work out a similar effect simple enough. The code below shows you a solution that could easily be wrapped in a custom user control called fieldset.
<Grid Width="500" VerticalAlignment="Center">
<!-- top fieldset thing -->
<Grid VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="35" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="Border">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="BorderThickness" Value="0,5,0,0" />
<Setter Property="BorderBrush" Value="white" />
<Setter Property="Margin" Value="0,-2,0,0" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10,-15,10,0" />
<Setter Property="FontSize" Value="30" />
</Style>
</Grid.Resources>
<Border Grid.Column="0" />
<TextBlock Grid.Column="1" Text="User Info" />
<Border Grid.Column="2" />
</Grid>
<!-- regular form fields -->
<Border BorderBrush="White" BorderThickness="5,0,5,5">
<StackPanel Margin="20">
<TextBox Header="Salutation" />
<TextBox Header="First Name" />
<TextBox Header="Middle Name" />
<TextBox Header="Last Name" />
<Button Margin="0,5,-3,0" HorizontalAlignment="Right">Save Data</Button>
</StackPanel>
</Border>
</Grid>
It looks something like this:
It's not 100% perfect - or, maybe... it is.
Best of luck!

Xaml Inherited StaticResource Styles

I am using Style Resources for my buttons.
Just wondering what is better to do.
<StackPanel Grid.Row="1">
<Button Content="Create Event" Click="CreateEvent_Click" Style="{StaticResource NavigationButton}" />
<Button Content="Search Event" Click="SearchEvent_Click" Style="{StaticResource NavigationButton}" />
<Button Content="My Events" Click="MyEvents_Click" Style="{StaticResource NavigationButton}" />
</StackPanel>
So, if I have many buttons I will need to write always Style="{StaticResource NavigationButton}"
Or to choose this one:
<StackPanel Grid.Row="1">
<StackPanel.Resources>
<Style TargetType="Button" BasedOn="{StaticResource NavigationButton}" />
</StackPanel.Resources>
<Button Content="Create Event" Click="CreateEvent_Click" />
<Button Content="Search Event" Click="SearchEvent_Click" />
<Button Content="My Events" Click="MyEvents_Click" />
</StackPanel>
Best is to put the styling in the App.xaml under App Resources. This is a better solution then on page because the resource will only by created once (instead of on multiple pages when reused).
Also, you can specify a target type like the following. This way you will not have to reference a certain style the way you did in your example. You just define your style here:
<Application.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Black" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Width" Value="80" />
<Setter Property="Margin" Value="10" />
</Style>
</Application.Resources>

Styling ListBox with Static Content

I have a set of static content that I want in a ListBox control.
<ListBox>
<ListBox.Items>
<ListBoxItem>
<Image />
<TextBlock Text="One" />
</ListBoxItem>
<ListBoxItem>
<Image />
<TextBlock Text="Two" />
</ListBoxItem>
<ListBoxItem>
<Image />
<TextBlock Text="Three" />
</ListBoxItem>
</ListBox.Items>
</ListBox>
How do I go about styling this? I know I can style each ListBoxItem individually, and I know how to style when data bound, but how do I style the a listbox item template when using static content like this?
You can define the items as low-level objects and use data-templating, which may not be the same as styles but properties are only set once as well:
<ListBox xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ListBox.Items>
<sys:String>one</sys:String>
<sys:String>two</sys:String>
<sys:String>three</sys:String>
</ListBox.Items>
<ListBox.ItemTemplate>
<DataTemplate>
<!-- "Style" this at will -->
<StackPanel>
<Image />
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
(To style the wrapping ListBoxItems you can try using an implicit style defined in the ListBox.Resources)
The following only works in WPF
Add a style to the resources of the ListBox and only set the TargetType and not the x:Key, it will be applied automatically.
You can even nest this automatic application using Resources, e.g.:
<ListBox>
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Resources>
<Style TargetType="{x:Type Image}">
<Setter Property="Width" Value="100"/>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Blue"/>
</Style>
</Style.Resources>
</Style>
</ListBox.Resources>
<!-- Items here -->
</ListBox>