Applying a style to all the TextBlocks that are children of StackPanel - wpf

Suppose I have a layout as below:
<Grid>
<TextBlock........ />
<StackPanel>
<TextBlock ...../>
<!--Other Elements-->
</StackPanel>
<TextBlock........ />
<StackPanel>
<TextBlock ...../>
<!--Other Elements-->
</StackPanel>
<TextBlock........ />
<StackPanel>
<TextBlock ...../>
<!--Other Elements-->
</StackPanel>
</Grid>
Now I want to apply a style like below to all the textblocks that are children of StackPanel in above mentioned layout.
<Style TargetType={x:Type TextBlock}>
<Setter Property="FontSize" Value="20" />
<Style>

First Method:
Example 1:
<Window.Resources>
<Style TargetType="StackPanel">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="20" />
</Style>
</Style.Resources>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock/>
</StackPanel>
<StackPanel>
<TextBlock />
</StackPanel>
Example 2: if you want textblock-stackpanel in particular grid
<Window.Resources>
<Style x:Key="Textblockstyle" TargetType="Grid">
<Style.Resources>
<Style TargetType="StackPanel">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="20" />
<Setter Property="Foreground" Value="Green"/>
</Style>
</Style.Resources>
</Style>
</Style.Resources>
</Style>
</Window.Resources>
<Grid>
<StackPanel Height="100" VerticalAlignment="top" Width="100">
<TextBlock Text="Another Grid" />
</StackPanel>
<Grid Style="{StaticResource Textblockstyle}">
<StackPanel Height="100" HorizontalAlignment="Left" Width="100">
<TextBlock Text="Textblock1" />
</StackPanel>
<StackPanel Height="100" HorizontalAlignment="Right" Width="100">
<TextBlock Text="Textblock2"/>
</StackPanel>
</Grid>
</Grid>
Second Method :Give style name to every textblock in stackpanel
<Window.Resources>
<Style x:Key="Textblockstyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="20" />
<Setter Property="Foreground" Value="Green"/>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock Text="abc" Style="{StaticResource Textblockstyle}"/>
<!--Other Elements-->
</StackPanel>

Related

Moving items down when adding error info using INotifyDataErrorInfo

I have for example a combobox and if it is not chosen then I am displaying an error message under it.
When the message is displayed it is displayed on top of the control that is under the combobox.
Is there a way to move the control(s) under the combobox down when the error message is shown?
<UserControl.Resources>
<Style x:Key="ErrorStackPanel" TargetType="{x:Type StackPanel}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Margin" Value="0 20 0 5"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ErrorComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="MinWidth" Value="180" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Vertical" SnapsToDevicePixels="True">
<!--Placeholder for the TextBox itself-->
<AdornedElementPlaceholder x:Name="textBox" />
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ErrorContent}"
Foreground="Maroon"
FontWeight="Bold"
Margin="5 2 0 0"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="2" Margin="10 5">
<Label Content="Switch" />
<ComboBox Style="{StaticResource ErrorComboBox}" ItemsSource="{Binding Switches}" SelectedItem="{Binding SelectedSwitch}"
DisplayMemberPath="Name" HorizontalAlignment="Left">
</ComboBox>
</StackPanel>
<StackPanel Grid.Row="3" Margin="10 10" Style="{StaticResource ErrorStackPanel}">
<RadioButton GroupName="pres"
IsChecked="{Binding TriggerOnPress}"
Content="On" Margin="0 5" />
<RadioButton GroupName="pres"
IsChecked="{Binding TriggerOnPress, Converter={valueconverters:BoolInverterConverter}}"
Content="Off" Margin="0 5"/>
</StackPanel>
StackPanel doesn't have error state. Apply trigger to ComboBox and change bottom margin:
<Style x:Key="ErrorComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="MinWidth" Value="180" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
...
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Margin" Value="0 0 0 20"/>
</Trigger>
</Style.Triggers>
</Style>

How to display multiple images as thumbnails in xaml

I am trying to create xaml page in silver light application. How to create a page like this, I have created a xaml page, but I can't create like this, my code is...
<UserControl x:Class="XXX.Views.Attachment.AttachmentViewer"
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="clr-namespace:xxx.Controls"
xmlns:local2="clr-namespace:xxx.Controls"
xmlns:XXX="clr-namespace:xxx.Controls;assembly=XXX.SL"
xmlns:baseconverters="clr-namespace:System.Windows.Converters;assembly=XXX.SL"
mc:Ignorable="d"
d:DesignHeight="800" FontFamily="{StaticResource MainFont}" d:DesignWidth="350">
<Grid x:Name="LayoutRoot" >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style x:Key="HeaderStyle" TargetType="TextBlock" >
<Setter Property="Margin" Value="5"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="20"/>
</Style>
</Grid.Resources>
<TextBlock Text="attachments" Style="{StaticResource HeaderStyle}"/>
<Rectangle Height="2" VerticalAlignment="Bottom" Fill="{StaticResource ColorDefaultGray}" Margin="0,40,0,5"/>
<ListView Grid.Row="1" x:Name="FileListItemsControl" VerticalAlignment="Top" Height="200" Margin="20" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Thumbnail, Converter={StaticResource ThumbnailToImageConverter}}" Height="150" Width="300" />
<TextBlock Text="{Binding FileName}" Style="{StaticResource BodyTextBlockStyle}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</UserControl>
it shows the name ListView does not exist, please find the attached image.
ListView is not found because it is not part of the version of Silverlight you are using.
You can apply a style to a ListBox control and replacing the item panel template with a WrapPanel from silverlight Toolkit.
Here is a Resource Dictionary with some styles that can be applied to ListBox controls to get he result you displayed in your attached image.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
xmlns:System="clr-namespace:System;assembly=mscorlib">
<!--Wrapping ListBox Styles-->
<Style x:Key="StretchedItemContainerStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
<Style x:Key="ListBox_StretchedItemStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle" Value="{StaticResource StretchedItemContainerStyle}"/>
</Style>
<Style x:Key="ListBox_HorizontalWrapStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle" Value="{StaticResource StretchedItemContainerStyle}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" Margin="0"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ScrollViewer VerticalScrollBarVisibility="Auto" BorderBrush="{x:Null}" >
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListBox_VerticalWrapStyle" TargetType="ListBox">
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
</Style>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate >
<toolkit:WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<!--End Wrapping ListBox Styles-->
</ResourceDictionary>
With the ListBox_HorizontalWrapStyle you just need to apply it to your target ListBox control
<ListBox Grid.Row="1" x:Name="FileListItemsControl" VerticalAlignment="Top" Height="200" Margin="20" Style={StaticResource ListBox_HorizontalWrapStyle} >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Thumbnail, Converter={StaticResource ThumbnailToImageConverter}}" Height="150" Width="300" />
<TextBlock Text="{Binding FileName}" Style="{StaticResource BodyTextBlockStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Optionally apply multiple styles

Let's say I have a extremly simplified xaml as follows:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="converter" />
<Style TargetType="FrameworkElement" x:Key="maybeCollapsed">
<Setter Property="Visibility" Value="{Binding Collapsed, Converter={StaticResource converter}}" />
</Style>
</UserControl.Resources>
<StackPanel>
<Label FontWeight="Bold" Content="Header" x:Name="Header" />
<TextBox Text="Name" Style="{StaticResource maybeCollapsed}" />
<TextBox Text="{Binding Name1}" Style="{StaticResource maybeCollapsed}"/>
</StackPanel>
</UserControl>
How could I apply a second style to all elements that use the maybeCollapsed-style, setting the IsTabStopto False? I cannot do this in the style itself, as IsTabStop is not a member of FrameworkElements.
Use Control.IsTabStop instead
<Style TargetType="FrameworkElement" x:Key="maybeCollapsed">
<Setter Property="Visibility" Value="{Binding Collapsed, Converter={StaticResource converter}}" />
<Setter Property="Control.IsTabStop" Value="False" />
</Style>

WPF StackPanel content vertical alignment

Is there a way in XAML to say that I want to center-align vertically all components inside a horizontal-oriented StackPanel?
I achieve the desired result with the below XAML:
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"/>
<Button VerticalAlignment="Center"/>
<TextBox VerticalAlignment="Center"/>
<Button VerticalAlignment="Center"/>
<TextBlock VerticalAlignment="Center"/>
</StackPanel>
But I need to repeat the VerticalAlignment="Center" for each control separately.
Is there a way to declare on the StackPanel level something like below?
<StackPanel Orientation="Horizontal" VERTICALCONTENTALIGNMENT="Center">
<TextBlock/>
<Button/>
<TextBox/>
<Button/>
<TextBlock/>
</StackPanel>
Put the StackPanel inside a Grid and set VerticalAlignment="Center" on the StackPanel
<Grid>
<StackPanel VerticalAlignment="Center">
...
</StackPanel
</Grid>
You can define style for StackPanel with Trigger which sets VerticalAlignment of all children:
<Style x:Key="HorizontalStackPanel" TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Horizontal" />
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center" />
</Trigger>
</Style.Triggers>
</Style>
And apply this style:
<StackPanel Style="{StaticResource HorizontalStackPanel}">
<TextBlock />
<Button />
<TextBox />
<Button />
<TextBlock />
</StackPanel>
It works for me.
The whole code:
<Window x:Class="WpfApplication11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="HorizontalStackPanel" TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Horizontal" />
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<StackPanel Style="{StaticResource HorizontalStackPanel}">
<TextBlock Text="One"/>
<Button Content="Two"/>
<TextBox Text="Three"/>
<Button Content="Four"/>
<TextBlock Text="Five"/>
</StackPanel>
</Grid>
</Window>
Define a style like this;
<Style x:Key="StackHorizontal" TargetType="StackPanel">
<Style.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Style.Resources>
</Style>
Just use this:
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock/>
<Button/>
<TextBox/>
<Button/>
<TextBlock/>
</StackPanel>

Question about WPF Resources/Styles & Scope

i am just beginning WPF and wonder why this works
<Window ...>
<Window.Resources>
<Style x:Name="buttonStyle">
<Style.Setters>
<Setter Property="Button.FontWeight" Value="Bold" />
<Setter Property="Button.Foreground" Value="Aqua" />
</Style.Setters>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button ... Style="{StaticResource buttonStyle}" />
</StackPanel>
</Grid>
</Window>
but this fails,
<Window ...>
<Window.Resources>
<Style x:Name="buttonStyle">
<Style.Setters>
<Setter Property="Button.FontWeight" Value="Bold" />
<Setter Property="Button.Foreground" Value="Aqua" />
</Style.Setters>
</Style>
</Window.Resources>
<Grid>
<StackPanel ...>
<StackPanel.Resources>
<Style x:Name="buttonStyle2">
<Setter Property="Button.Foreground" Value="Red" />
</Style>
</StackPanel.Resources>
<Button ... Style="{StaticResource buttonStyle}" />
<Button ... Style="{StaticResource buttonStyle2}" />
</StackPanel>
</Grid>
</Window>
the error is
The resource "buttonStyle2" could not be resolved
The resource "buttonStyle" could not be resolved
buttonStyle resolves ok in the 1st code (without the 2nd button)
arr... my bad, i should be using x:Key not x:Name

Resources