How to center a TextBlock inside a GridViewColumn? (Sample xaml included) - c#

<Window x:Class="EffectsWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<ListView ItemsSource="{Binding EffectsViewModel.Effects}">
<ListView.View>
<GridView>
<GridViewColumn Width="200" Header="Effects">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock HorizontalAlignment="Center"
Text="{Binding Name}"
TextAlignment="Center" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Window>
Effect is just a type has a Name property that returns a string, but the text is still not centered inside its cell.
Any ideas on how to fix it?

You can Stretch the HorizontalContentAlignment for ItemContainerStyle
<ListView ItemsSource="{Binding EffectsViewModel.Effects}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<!--...-->
</ListView>
Update
You should be able to combine the alternating row colors with HorizontalContentAlignment like this. I tried it and it seems to be working
<ListView ItemsSource="{Binding EffectsViewModel.Effects}"
AlternationCount="2">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightBlue"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<!--...-->
</ListView>

Try using an app like snoop to visually inspect the properties of your app and you can see where things are not aligning like you expect.

Related

How can I change background behind border (ListView.ItemTemplete->datatemplete) when I hover or click?

My problem is when I click or hover in ListViewItem which also show the silver background:
enter image description here
this is my code xaml:
<ListView
Margin="0,30,0,0"
Height="600"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Name="ListViewFC" ItemsSource="{Binding ListWords, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}" >
<ListView.ItemTemplate>
<DataTemplate>
<Border
Width="340"
x:Name="Border"
Height="80"
Background="Pink"
CornerRadius="15"
BorderThickness="1"
>
<Grid>
<TextBlock
VerticalAlignment="Center"
x:Name="txtContent"
Foreground="Black"
Text="{Binding Question1,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
TextWrapping="NoWrap"
Margin="30 0 0 0"
FontSize="15"
/>
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListViewItem}}, Path=IsSelected}" Value="True">
<Setter TargetName="Border" Property="Background" Value="White" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I want that When I hover or click It don't show the silver background.
pls, help me .Thanks.
Add this inside your ListView:
<ListView.Resources>
<Style BasedOn="{StaticResource TextBlockStyle}" TargetType="{x:Type TextBlock}" />
<Style BasedOn="{StaticResource ListViewItemStyle}" TargetType="{x:Type ListViewItem}" />
</ListView.Resources>
Then add this outside of your ListView (this displays a background of gold on hover):
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Gold" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
The default ControlTemplate of the ListView contains a Border with Padding of 2X. Hence you have to change its template something like this
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>

Apply (xaml) style to DataTemplate control

I would like to apply a style, in this case of a 'ListViewItem', to a control within a DataTemplate.
Style (sample) code:
<Style x:Key="ListViewItemStyle" TargetType="ListViewItem">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="Blue" />
<Setter Property="BorderBrush" Value="Blue" />
<Setter Property="Foreground" Value="White"/>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
DataTemplate (sample) code:
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumnHeader Content="Text"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding MyImage}"/>
<Label Content="{Binding MyLabelText}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
What is the solution to apply the Background, BorderBrush and Foreground style to the <Label> within the DataTemplate?
Thank you in advance.
Note: I already read the question and answers of 'Applying style to elements inside a DataTemplate', but I would like to use xaml (so without C# code).
The following XAML styles the ListViewItem (assuming Items is your collection):
<ListView ItemsSource="{Binding Items}">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="Blue" />
<Setter Property="BorderBrush" Value="Blue" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsSelected}" Value="True">
<DataTrigger.Setters>
<Setter Property="Foreground" Value="White"></Setter>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumnHeader Content="Text"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding MyImage}" Width="20"/>
<Label Content="{Binding MyLabelText}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>

ListView how to change ItemsPanel in codebehind instead than in xaml

I had this in my xaml that formatted my listView. That works but I have to add a mode complicated logic so that this has to be applied
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation = "Horizontal" Width = "250" Background = "{x:Null}" VerticalAlignment = "Top"></WrapPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
so now I'd need to apply the code above in code behind.
---EDIT for Martino Bordin---
Please tell me what I have misunderstood:
1a. I have defined a style in my listview:
<ListView x:Name="lvPPtab1" Grid.Row="2" FontSize="12" Background="{x:Null}" BorderBrush="Gainsboro" BorderThickness="5" Margin="10,12.2,10,8.4" VerticalAlignment="Stretch" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown" SelectionChanged="ListView_SelectionChanged">
<ListView.Resources>
<Style x:Key="ListViewStyle" TargetType="ListView">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate >
<WrapPanel Orientation="Horizontal" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
2a.I set it in my code behind only when I need it:
<ListView x:Name="lvPPtab1" Grid.Row="2" FontSize="12" Background="{x:Null}" BorderBrush="Gainsboro" BorderThickness="5" Margin="10,12.2,10,8.4" VerticalAlignment="Stretch" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown" SelectionChanged="ListView_SelectionChanged">
<ListView.Resources>
<Style x:Key="ListViewStyle" TargetType="ListView">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate >
<WrapPanel Orientation="Horizontal" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
lvPPtab1.Style = (Style)this.Resources["ListViewStyle"];
and all what I see is... nothing listView empty.
Then I tried to stick to what you said and so I did that:
1b. in the xaml
<ListView x:Name="lvPPtab1" Grid.Row="2" FontSize="12" Background="{x:Null}" BorderBrush="Gainsboro" BorderThickness="5" Margin="10,12.2,10,8.4" VerticalAlignment="Stretch" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown" SelectionChanged="ListView_SelectionChanged">
<ListView.Resources>
<ItemsPanelTemplate x:Key="ListViewStyle" >
<WrapPanel Orientation="Horizontal" VerticalAlignment="Top"></WrapPanel>
</ItemsPanelTemplate>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
in the code behind:
lvPPtab1.ItemsPanel = (ItemsPanelTemplate)this.Resources["ListViewStyle"];
but again nothing! All empty where am I wrong?????
Put the template in the resources dictionary, give a x:Name to your listview, then you can access its properties in the code behind:
myListView.ItemsPanel
myListView.ItemsPanel = (ItemsPanelTemplate)this.Resources["MyListViewPanelTemplate"];

A value of type 'Style' cannot be added to a collection or dictionary of type 'UIElementCollection'

I have the following XAML code. I want alternate lines in my listview which will be populated dynamically though the code at run time.
I'm using the following XAML code but it give error called Error8 A value of type 'Style' cannot be added to a collection or dictionary of type 'UIElementCollection'.
<ListView Grid.Column="1" Grid.Row="10" BorderBrush="#FFA8CC7B" Height="133" HorizontalAlignment="Left" Margin="0,0,0,93" Name="lstViewAppsList" VerticalAlignment="Top" Width="596"
ItemContainerStyle="{StaticResource alternatingStyle}" AlternationCount="2">
<ListView.View>
<GridView>
<GridViewColumn Header="Apps" Width="150" />
<GridViewColumn Header="Package" Width="350" />
</GridView>
</ListView.View>
</ListView>
<Style x:Key="alternatingStyle" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="BValue="LightSkyBlue"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Orange"/>
</Trigger>
</Style.Triggers>
</Style>
It needs to be in a ResourceDictionary of some sort, you can add to the ListView or the Window/Page resources or even an external resource file
<ListView.Resources>
<Style x:Key="alternatingStyle" TargetType="{x:Type ListViewItem}">
......
</Style>
<ListView.Resources>
So to add it to your example above
<ListView Grid.Column="1" Grid.Row="10" BorderBrush="#FFA8CC7B" Height="133" HorizontalAlignment="Left" Margin="0,0,0,93" Name="lstViewAppsList" VerticalAlignment="Top" Width="596" AlternationCount="2">
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
......
</Style>
<ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Apps" Width="150" />
<GridViewColumn Header="Package" Width="350" />
</GridView>
</ListView.View>
</ListView>
You need to place this style in ResourceDictionary. If you are using , Place the style as follows,
<Window.Resources>
<Style x:Key="alternatingStyle" TargetType="{x:Type ListViewItem}">
</Style>
</Window.Resources>
Regards,
Riyaj Ahamed I

Change the colour of the particular element in Treeview WPF

I have a Treeview in my WPF application. On the fly, in run time, If the element of the Tree meets certain condition, It should change its Font color from Black To Red.!
XAML
<TreeView Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" Name="treeView1"
VerticalAlignment="Stretch"
SelectedItemChanged="treeView1_SelectedItemChanged" HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Top" BorderThickness="0,0,0,1" BorderBrush="LightGray">
<TreeViewItem Header="Head Tree" ItemsSource="{Binding MainComps}">
<TreeViewItem.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Foreground" Value="RED" />
</DataTrigger>
</Style.Triggers>
</Style>
</TreeViewItem.ItemContainerStyle>
<TreeViewItem.Resources>
<HierarchicalDataTemplate DataType="{x:Type TextBlock}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Head Tree" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:MainCompViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Maincompname}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:FeatureViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FeatureName}" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:CompViewModel}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Component}" />
</StackPanel>
</DataTemplate>
</TreeViewItem.Resources>
</TreeViewItem>
</TreeView>
Code behind
private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if(selected Item meets certain condition)
{
//Change color of tree node
}
}
How can I change the color of particular Node and leave it in the same color SO that when expanded again It should be in RED.
Any help would be appreciated.
You could create a boolean property in the model which is true when the elements meets the condition. Then you bind the Foreground like so:
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=BoolProp}" Value="False">
<Setter Property="Foreground" Value="Blue"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=BoolProp}" Value="True">
<Setter Property="Foreground" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
or with converter:
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="Foreground" Value="{Binding Path=BoolProp, Converter={StaticResource ResourceKey=TheKey}}"/>
</Style>
</TreeView.ItemContainerStyle>
Just change the Foreground:
TreeViewItem ti = (TreeViewItem)treeView1.SelectedItem;
ti.Foreground = Brushes.Red;
That is embedded into the template. You can only change the color by copying the default Aero-Style for the control and changing the hard-coded value.
Or by drilling down the visual tree on-load to change it that way.
To get the default style & tenmplate go through this MSDN
Can also check step wise EXAMPLE from here.

Categories