WPF: Button not taking the full space in a Listbox - wpf

I've a ListBox, in which I will have some Button added by prism.
For now, I've the following code(with some dummy button here just for testing purpose:
<DockPanel LastChildFill="True">
<ListBox HorizontalContentAlignment="Stretch" Padding="0" Margin="0" BorderBrush="Black" DockPanel.Dock="Left" HorizontalAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Resources>
<Style TargetType="Button">
<Setter Property="Height" Value="60" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Margin" Value="0" />
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListBox.Resources>
<Button>Button 1</Button>
<Button >Button 2</Button>
</ListBox>
<ContentControl></ContentControl>
</DockPanel>
The issue that I'm having currently is that my buttons are not taking the full space:
How to make sure it use all the available space?
Is there some way to ensure that all buttons will be have the height = to the width?
(just to be clear, I don't want anything set on the button since they will be provided by Prism from different modules)
When I run the application and focus an object, it seems we see that the ListBoxItemis taking the full place but the Button inside isn't:

How to make sure it use all the available space?
This is due to how the ListBox control's template is designed. To remove the small margin at the left and right of the button, set Padding=0 for the ListBoxItem style.
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0" />
</Style>
</ListBox.ItemContainerStyle>
Is there some way to ensure that all buttons will be have the height = to the width?
You could do a RelativeSource binding to bind the container's height to the actual width of the parent ListBox:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Height" Value="{Binding RelativeSource={RelativeSource AncestorType=ListBox},Path=ActualWidth}" />
</Style>
</ListBox.ItemContainerStyle>

Related

GridViewColumnHeader not spanning whole ListView width

I am having trouble with the layout of a ListView / GridView combination in my WPF project. The columnheaders are just not spanning the whole width of the parent ListView. I tried to find documentation everywhere but didn't find any clues about the underlying containers / control templates.
I guess the standard control template of the header contains something that I am not taking care of, I just cannot wrap my head around it.
The (simplified) ListView has a few pixel space to the left and to the right of the row containing the headers, where the background of the parent ListView is visible:
https://i.imgur.com/XijV88a.jpg
Question: How can I make the columnheaders span the whole width of the ListView and make the few pixels space disappear?
My XAML:
<ListView Padding="0"
BorderThickness="0"
Background="Red">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="Black" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn Header="1" Width="40"/>
<GridViewColumn Header="2" Width="40"/>
<GridViewColumn Header="3" Width="40"/>
</GridView>
</ListView.View>
<ListViewItem> 1 </ListViewItem>
<ListViewItem> 2 </ListViewItem>
</ListView>
The only way so far to achieve the look I am going for is to change the background of the listview to the same color as the headers - there has to be a better way, though. Any help is appreciated!
This column does not support "*" as width argument so you cannot easily say - fill the rest...
What you should do is hook up on SizeChanged event of the ListView and there do the calculations. So for instance, in your case, if we wanted first two columns to take 40 each and the third column to take the rest you would do it like so:
private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
ListView listView = sender as ListView;
GridView gView = listView.View as GridView;
var workingWidth = listView.ActualWidth - SystemParameters.VerticalScrollBarWidth;
gView.Columns[0].Width = 40;
gView.Columns[1].Width = 40;
gView.Columns[2].Width = workingWidth - 80;
}
EDIT
For the gaps(to the left and to the right) in the header row you want to alter the ColumnHeaderContainerStyle like so:
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="Black" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Margin" Value="-2,0,-2,0" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</GridView.ColumnHeaderContainerStyle>
So make sure you just reduce the margin by -2 on each side.

Can I apply a WPF style to an element only in a certain layout?

I have a TextBlock style like this:
<Style TargetType="TextBlock" x:Key="FormLabel">
<Setter Property="Height" Value="20" />
<Setter Property="Margin" Value="10" />
<Setter Property="TextAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
I use it in Grid based forms, e.g:
<TextBlock Text="Code" Grid.Row="1" Grid.Column="0" Style="{StaticResource FormLabel}" />
Now instead of repeating the style name on every TextBlock in the grid, I would prefer to e.g. have a Grid style like:
<Style TargetType="Grid" x:Key="FormGrid">
<Setter Property="Width" Value="400" />
...
</Style>
Then I would, if possible, like to modify my TextBlock style to only apply to that element when it is a child element of a Grid with style FormGrid.
Is this possible, and if so, how can I achieve it?
This is indeed possible by using an implicit style within another style as a resource. Take this example:
...
<Window.Resources>
<Style x:Key="FormGrid" TargetType="Grid">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="Height" Value="20" />
<Setter Property="Margin" Value="10" />
<Setter Property="TextAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Style.Resources>
<Setter Property="Width" Value="400" />
</Style>
</Window.Resources>
<StackPanel>
<Grid Style="{StaticResource FormGrid}">
<TextBlock Text="This text block is styled with FormGrid TextBlock implicit style."/>
</Grid>
<TextBlock Text="This text block uses the default style."/>
</StackPanel>
...
This is not possible by out of the box WPF abilities. What you are looking here is CSS like style selectors. WPF Only allows style inheritance through BasedOn property. I am not sure if this could be an alternative, but you can define that specific TextBlock style as part of that grid resources and target to match any textblock inside of it.
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Height" Value="20" />
<Setter Property="Margin" Value="10" />
<Setter Property="TextAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Grid.Resources>

Customize WPF Toolkit autocompletebox

WPF Toolkit library has Autocompletebox control.
1. How to place an icon at the left of its Textbox part?
2. How to add shadow to the borders of the suggestions popup?
Changing TextBoxStyle property does not give any results.
<!-- xmlns:extendedControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" -->
<extendedControls:AutoCompleteBox>
<extendedControls:AutoCompleteBox.TextBoxStyle>
<Style TargetType="TextBox">
<Setter Property="Padding" Value="20,0,0,0" />
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/img.png" Stretch="None" AlignmentX="Left" />
</Setter.Value>
</Setter>
</Style>
</extendedControls:AutoCompleteBox.TextBoxStyle>
</extendedControls:AutoCompleteBox>
The Autocompletebox have got a property : TextBoxStyle where you can chose the style of the textbox.
Or you can do that in the property Style like that :
<UserControl.Resources>
<Style TargetType="TextBox" x:Key="TextboxStyle2">
<Setter Property="MaxLength" Value="74" />
<Setter Property="Width" Value="300" />
</Style>
<Style TargetType="controls:AutoCompleteBox" x:Key="TextBoxStyle">
<Setter Property="TextBoxStyle" Value="{StaticResource TextboxStyle2}" />
<Setter Property="IsTextCompletionEnabled" Value="True" />
</Style>
</UserControl.Resources>
/*...*/
<controls:AutoCompleteBox Name="Titre" Style="{StaticResource TextBoxStyle}"/>
But i don't know how to add the shadow. Try the others properties. =)
Edit :
To change background, there is already some tutoriels.
how to separate the background image in wpf textbox?
Exemple :
<Style TargetType="TextBox" x:Key="TextboxStyle2">
<Setter Property="MaxLength" Value="74" />
<Setter Property="Width" Value="300" />
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="../../../Ressources/Icones/Find_5650.ico" Stretch="None" AlignmentX="Left" AlignmentY="Top" />
</Setter.Value>
</Setter>
</Style>

Silverlight datagrid columnheader change font color

Is it possible to change the font color for the column headers in a datagrid?
I've already applied some styling which changes the background, but i can't figure out how to change the font color, not for the element, but for the header.
the XAML I'm using is from this thread: Change background color of Datagrid Header in Silverlight
Hi add a style to your resource and set the style,
<Style x:Key="GridHeaderStyle" ControlTemplate TargetType="primitives:DataGridColumnHeader">
<Setter Property="FontSize"
Value="14" />
<Setter Property="FontWeight"
Value="Bold" />
<Setter Property="Foreground"
Value="{StaticResource xrxGray_I}" />
<Setter Property="Background"
Value="{StaticResource xrxGray_B}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Height="50" Width="100">
<TextBlock Text="{TemplateBinding Header}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

WPF Add a Border to a TextBlock

Is it possible to add a border to a textblock. I need it to be added in the setter property below code:
<Style x:Key="notCalled" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="2,2,2,2" />
<Setter Property="Background" Value="Transparent" />
</Style>
You need to wrap your TextBlock in a Border. Example:
<Border BorderThickness="1" BorderBrush="Black">
<TextBlock ... />
</Border>
Of course, you can set these properties (BorderThickness, BorderBrush) through styles as well:
<Style x:Key="notCalledBorder" TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Black" />
</Style>
<Border Style="{StaticResource notCalledBorder}">
<TextBlock ... />
</Border>
A TextBlock does not actually inherit from Control so it does not have properties that you would generally associate with a Control. Your best bet for adding a border in a style is to replace the TextBlock with a Label
See this link for more on the differences between a TextBlock and other Controls

Resources