Silverlight Textbox: Text wrapping without a fixed width - silverlight

My Textblock isn't wrapping unless I give it a fixed width. The problem is that I don't know what the width should be, as it needs to simply take up whatever's left.
<Style TargetType="TextBlock" x:Key="Label">
<Setter Property="FontSize" Value="20" />
</Style>
<Style TargetType="TextBlock" x:Key="Value">
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="FontSize" Value="16" />
</Style>
<localControls:DetailRegion>
<StackPanel Orientation="Horizontal" Width="230">
<TextBlock Text="Beliefs and Goals:" Style="{StaticResource Label}" />
<TextBlock Text="{Binding BeliefsAndGoals}" Style="{StaticResource Value}" />
</StackPanel>
</localControls:DetailRegion>

Ugh. As always, the problem is the StackPanel. If I switch to a grid with two columns (one auto, the other *) then it works as expected.
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Beliefs & Goals:" Style="{StaticResource Label}" />
<TextBlock Text="{Binding BeliefsAndGoals}" Style="{StaticResource Value}" Grid.Column="1" />
</Grid>

Related

Columns with SharedSizeGroups in ItemsControl don't use full available width

The cyan color is the background of the ItemsControl. As you can see it occupies the entire window width.
Now I want, the center column (with text "unknown") to stretch horizontally. Can't get it done, no clue what I am missing this time.
My xaml
<GroupBox Grid.Row="1" BorderThickness="2" BorderBrush="Black">
<ItemsControl Background="Aquamarine"
ItemsSource="{Binding
RelativeSource={RelativeSource AncestorType={x:Type local:AppGroup}},
Path=AppItemSource}"
Grid.IsSharedSizeScope="True"
HorizontalContentAlignment="Stretch">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name"/>
<ColumnDefinition Width="*" SharedSizeGroup="State"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Buttons"/>
</Grid.ColumnDefinitions>
<TextBlock Style="{StaticResource AppNameColumnText}" Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Style="{StaticResource AppStateColumnText}" Grid.Column="1" Text="{Binding StatusText}" TextAlignment="Center" HorizontalAlignment="Stretch"/>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="20"/>
<Setter Property="Height" Value="20"/>
<Setter Property="Margin" Value="5"/>
</Style>
</StackPanel.Resources>
<Button Style="{StaticResource StartButton}" Command="{Binding StartCommand}"/>
<Button Style="{StaticResource StopButton}" Command="{Binding StopCommand}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</GroupBox>
I have:
Set my ItemsControl with HorizontalContentAlignment is true
The center column is defined with "*"
The TextBlock is allowed to stretch.
What else do I need to tell WPF ?
For completeness, the defined styles which seem harmless to me.
<Style x:Key="AppNameColumnText" TargetType="TextBlock">
<Setter Property="Margin" Value="20,0,20,0"/>
<Setter Property="FontSize" Value="26"/>
</Style>
<Style x:Key="AppStateColumnText" TargetType="TextBlock">
<Setter Property="Margin" Value="20,0,20,0"/>
<Setter Property="FontSize" Value="26"/>
</Style>
remove SharedSizeGroup="State" from column with * width, it will stretch as expected (and SharedSizeGroups on all other columns will ensure that central column has the same width):
<!-- <ColumnDefinition Width="*" SharedSizeGroup="State"/> -->
<ColumnDefinition Width="*" />
documentation has an explanation:
Columns and rows that participate in size-sharing do not respect Star sizing. In the size-sharing scenario, Star sizing is treated as Auto.

How to show the separator in DataGrid.ColumnHeaderStyle with a transparent background? [duplicate]

I have used this xaml code to modify the background color of my DataGrid Header and the column separator visibility. My problem is that the column separators are elminated so the column headers look a little bit different:
this is my code :
<DataGrid AutoGenerateColumns="False" Grid.ColumnSpan="9" Grid.Row="1" Height="82" HorizontalAlignment="Left" Margin="99,427,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="363" Background="#9DB9EB" >
<DataGrid.Columns>
<DataGridTextColumn Header="Header1" />
<DataGridTextColumn Header="Header2" />
</DataGrid.Columns>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#cee8ef" />
<Setter Property="BorderThickness" Value="2" />
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
How can I make the header column separtor visible?
Try this style
<Style TargetType="{x:Type DataGridColumnHeader}"
>
<Setter Property="Background"
Value="#cee8ef" />
<Setter Property="BorderThickness"
Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Content="{TemplateBinding Content}"
Grid.Column="0"
HorizontalAlignment="Center"
Margin="10,0,25,0" />
<Thumb HorizontalAlignment="Right"
Grid.Column="1"
Name="PART_HeaderGripper"
Margin="0,4,0,4"
Width="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hope it helps you, you can modify it further if you need it ...

stretch border to existing space

I have this:
<Border Background="Gray">
<TextBlock x:Name="Text"
Text="{Binding Name}"
Margin="0, 5"
FontSize="16"/>
</Border>
It looks like this: (There are three of those)
I want it to look like this:
(Border stretching to end of the space + some control over the height of the border.)
p.s. I do not have to use borders, anything that will achieve the same effect will do.
update: This is part of a DataTemplate for a ListBoxItem. It's defined in a style like this:
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border>
<TextBlock x:Name="Text"
Text="{Binding Name}"
Margin="0, 5"
FontSize="16"/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
I tried to set the HorizontalAlignment to "Stretch" and it didn't work. Any ideas?
A StackPanel will work if your TextBlock numbers are fixed:
<StackPanel Grid.Column="1">
<StackPanel.Resources>
<Style x:Key="style1" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="0,5" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Foreground" Value="White" />
</Style>
</StackPanel.Resources>
<TextBlock Text="Text 1" Style="{StaticResource style1}" />
<TextBlock Text="Text 2" Style="{StaticResource style1}" />
<TextBlock Text="Text 3" Style="{StaticResource style1}" />
</StackPanel>
Or if the TextBlock is generated base on some data source, use an ItemsControl:
<ItemsControl ItemsSource="{Binding}" >
<ItemsControl.Resources>
<Style x:Key="style1" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="0,5" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Foreground" Value="White" />
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="Text" Style="{StaticResource style1}" Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The easiest approach is to use grid rows.
Here is an example:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="text 1" Background="gray"/>
<TextBlock Grid.Row="2" Text="text 2" Background="gray"/>
<TextBlock Grid.Row="4" Text="text 3" Background="gray"/>
</Grid>
try this...
<Border Background="Gray" HorizontalAlignment="Stretch">
<TextBlock x:Name="Text"
HorizontalAlignment="Left"
Text="{Binding Name}"
Margin="0, 5"
FontSize="16"/>
</Border>
At last I found this as the easiest solution to accomplish exactly what I wanted:
I create a grid (with one column and one row)
I create a Rectangle inside (which automatically stretches to the grid space)
I create a textBox (which automatically renders on top of the Rectangle)
Here's how it looks like:
<Grid>
<Rectangle x:Name="fillColor" Fill="..."/>
<TextBox ... />
</Grid>

Make the header column separator visible

I have used this xaml code to modify the background color of my DataGrid Header and the column separator visibility. My problem is that the column separators are elminated so the column headers look a little bit different:
this is my code :
<DataGrid AutoGenerateColumns="False" Grid.ColumnSpan="9" Grid.Row="1" Height="82" HorizontalAlignment="Left" Margin="99,427,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="363" Background="#9DB9EB" >
<DataGrid.Columns>
<DataGridTextColumn Header="Header1" />
<DataGridTextColumn Header="Header2" />
</DataGrid.Columns>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#cee8ef" />
<Setter Property="BorderThickness" Value="2" />
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
How can I make the header column separtor visible?
Try this style
<Style TargetType="{x:Type DataGridColumnHeader}"
>
<Setter Property="Background"
Value="#cee8ef" />
<Setter Property="BorderThickness"
Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Content="{TemplateBinding Content}"
Grid.Column="0"
HorizontalAlignment="Center"
Margin="10,0,25,0" />
<Thumb HorizontalAlignment="Right"
Grid.Column="1"
Name="PART_HeaderGripper"
Margin="0,4,0,4"
Width="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hope it helps you, you can modify it further if you need it ...

Shadow under hovered ListBoxItem (and not under it's text)

I need shadow under ListBoxItem on MouseOver. Bottom code works but the whole listbox including the TextBlock's letters have a shadow:
<ListBox ItemContainerStyle="{StaticResource Style1}"
And the item Style:
<Style x:Key="Style1" TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Setter Property = "Effect" >
<Setter.Value>
<DropShadowEffect ShadowDepth="10" Direction="0" Opacity="1" BlurRadius="5" Color="Black"/>
</Setter.Value>
</Setter>
</Trigger>
Simplified DataTemplate:
<DataTemplate x:Key="TemplateSimple" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Title}" Grid.Column="0"/>
<TextBlock Text="{Binding FirstName}" Grid.Column="1"/>
<TextBlock Text="{Binding LastName}" Grid.Column="2"/>
Example is simplified.
I also tried adding to the DataTemplate:
<Rectangle Grid.Column="0" Fill="GreenYellow" Grid.ColumnSpan="3">
and assigning the shadow to it, but it would react only if TextBlocks are empty. Other ideas are appreciated.
EDIT:
As you can see it is not really a shadow but a blurry text. If it was a shadow, it would change much on changing shadow length:
See this post, How do I apply an effect to a Border but not to its contents in WPF?, which has some documentation on this "feature".
The easiest workaround in your case might be to give the Grid in your DataTemplate a background color:
<DataTemplate x:Key="TemplateSimple" >
<Grid Background="White" > ...
EDIT:
A more thorough approach would be to apply the DropShadowEffect to an element that lies beneath the text, but doesn't contain the text. For example, add a rectangle to your DataTemplate:
<DataTemplate x:Key="TemplateSimple" >
<Grid Margin="2" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Style="{StaticResource RectStyle1}"
Fill="Lime" Grid.ColumnSpan="3" />
<TextBlock Text="{Binding Title}" Grid.Column="0" />
<TextBlock Text="{Binding FirstName}" Grid.Column="1" />
<TextBlock Text="{Binding LastName}" Grid.Column="2" />
</Grid>
</DataTemplate>
..and instead of having the DropShadowEffect in Style1, put it in RectStyle1, but still triggered by IsMouseOver on the parent ListBoxItem:
<Style x:Key="RectStyle1" TargetType="Rectangle" >
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem},
Path=IsMouseOver,
Mode=OneWay}"
Value="True" >
<Setter Property="Effect" >
<Setter.Value>
<DropShadowEffect ShadowDepth="10" Direction="0"
Opacity="1" BlurRadius="5"
Color="Black" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>

Resources