WPF cant change listview background with gridview - c#

I have this markup and my background color will not stay null when its IsEnabled=false. I tried a style trigger that change it when it became disabled but it hasn't worked. How can I make my ListView background color null when its disabled with a gridview?
<ListView Background="{x:Null}" IsEnabled="False">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}"/>
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
<GridViewColumn Header="Email" DisplayMemberBinding="{Binding EmailAddress}"/>
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
in app.xaml
<Style TargetType="ListView">
<Setter Property="BorderThickness" Value="0"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>

Just try this,
<ListView Background="Transparent" IsEnabled="False">
<ListView.Template>
<ControlTemplate TargetType="ListView">
<Border Name="Border"
BorderThickness="1">
<ScrollViewer Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
<ItemsPresenter />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ListView.Template>
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding FirstName}" Header="First Name" />
<GridViewColumn DisplayMemberBinding="{Binding LastName}" Header="Last Name" />
<GridViewColumn DisplayMemberBinding="{Binding EmailAddress}" Header="Email" />
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>

Related

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>

How to change color for specific value in Listview

I want to change color according to value: Pass(Blue) and Fail(Red). I want to change only text color of state's value.
main.xaml
<ListView x:Name="record_List"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="203" Width="382" Margin="553,454,0,0"
BorderThickness="0">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn Header="State" Width="52"
DisplayMemberBinding="{Binding state}"/>
<GridViewColumn Header="Stuednt num" Width="80"
DisplayMemberBinding="{Binding snum}"/>
<GridViewColumn Header="Name" Width="75"
DisplayMemberBinding="{Binding name}"/>
<GridViewColumn Header="Check time"
DisplayMemberBinding="{Binding check_time}"/>
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewMouseLeftButtonDown"
Handler="ListViewItem_PreviewMouseLeftButtonDown"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Use style triggers for column State, you try:
Fixed:
<GridViewColumn Header="State" Width="52" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding state}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Black"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding state}" Value="Pass">
<Setter Property="Foreground" Value="Blue"/>
</DataTrigger>
<DataTrigger Binding="{Binding state}" Value="Fail">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
The easiest way would be to use style and DataTriggers:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Background" Value="Gray"/>
<Style.Triggers>
<DataTrigger Binding="{Binding testResult}" Value="Pass">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
<DataTrigger Binding="{Binding testResult}" Value="Fail">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>

How to Get the Index of ListView Row on Button Click

I am making a wpf Application and encountered a Problem.
I have used a listview and added a Button in it via Xaml.
<ListView x:Name="list_View" Grid.Column="2" Margin="0,0,0,53" Grid.Row="1" MouseDoubleClick="list_View_MouseDoubleClick" ItemContainerStyle="{DynamicResource alternatingListViewItemStyle}" AlternationCount="2">
<ListView.Style>
<Style TargetType="{x:Type ListView}">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Margin" Value="0"/>
</Style>
</ListView.Style>
<ListView.Resources>
<Style x:Key="alternatingListViewItemStyle" TargetType="{x:Type ListViewItem}">
<!-- setting row height here -->
<Setter Property="Height" Value="30" />
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="#E7F8FE"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Product Name" Width="100" DisplayMemberBinding="{Binding Product_Name}"/>
<GridViewColumn Header="Unit Price" Width="70" DisplayMemberBinding="{Binding Unit_Price}"/>
<GridViewColumn Header="Quantity" Width="50" DisplayMemberBinding="{Binding Quantity}"/>
<GridViewColumn Header="Total" Width="60" DisplayMemberBinding="{Binding Total}" />
<GridViewColumn Header="Delete" Width="60">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="X" Width="30" Click="Delete_Item_In_Cart_Click" Name="btn_Delete_Item_In_Cart">
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
The Lisview I got looks like this:
I want to get the index of Listview Row on Button Click.
The code behind button click is:
private void Delete_Item_In_Cart_Click(object sender, RoutedEventArgs e)
{
try
{
int index2 = list_View.SelectedIndex;
MessageBox.Show(index2.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
**Issue: **When I click on Button in any row of listview It always gives me the same index,
What I got as Output is:
Thanks in Advance
Finally I got my issue resolved. Here is the Solution and Process I followed.
1: First of All I added these lines to my existing Xaml in <ListView.Resourses/>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
<EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
</Style>
2: And For the C# Code, I added the SelectCurrentItem Handler Mentioned above in Xaml.
Here is the Code for the Event Handler that did the actual task for me.
private void SelectCurrentItem(object sender, KeyboardFocusChangedEventArgs e)
{
//By this Code I got my `ListView` row Selected.
ListViewItem item = (ListViewItem)sender;
item.IsSelected = true;
}
3: Now to get the Index of the selected ListView Row was Pretty much easy and simple for me. And the Old Code behind the Button Click worked Perfectly for me.
So Finally Here I am Giving All the Code that is fully tested and error free.
1: Xaml:
This is the code for ListView
<ListView x:Name="list_View" Grid.Column="2" Grid.Row="1" Margin="0,0,0,103">
<ListView.Style>
<Style TargetType="{x:Type ListView}">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Margin" Value="0"/>
</Style>
</ListView.Style>
<ListView.Resources>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
<EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
<Setter Property="Height" Value="30" />
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="#E7F8FE"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Product Name" Width="120" DisplayMemberBinding="{Binding Product_Name}"/>
<GridViewColumn Header="Unit Price" Width="70" DisplayMemberBinding="{Binding Unit_Price}"/>
<GridViewColumn Header="Quantity" Width="50" DisplayMemberBinding="{Binding Quantity}"/>
<GridViewColumn Header="Total" Width="60" DisplayMemberBinding="{Binding Total}" />
<GridViewColumn Header="Delete" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="X" Width="60" Click="Delete_Item_In_Cart_Click" Name="btn_Delete_Item_In_Cart" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
2: C# Code:
private void SelectCurrentItem(object sender, KeyboardFocusChangedEventArgs e)
{
ListViewItem item = (ListViewItem)sender;
item.IsSelected = true;
}
private void Delete_Item_In_Cart_Click(object sender, RoutedEventArgs e)
{
try
{
int index =0;
index = list_View.SelectedIndex;
MessageBox.Show(index.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Your current program is returning the index of selected row. On button click, the row will not get selected. To get the desired result select the row on button click.
Here is code for selecting the row on button click.
Code behind:
private void DeleteListItem(object sender, RoutedEventArgs e)
{
var curItem = ((ListBoxItem)listView.ContainerFromElement((Button)sender));
listView.SelectedItem = (ListBoxItem)curItem;
MessageBox.Show($"Selected index = {listView.SelectedIndex}");
// Add code for delete item here
}
XAML - List view sample code:
<ListView x:Name="listView" HorizontalAlignment="Left" Height="301" Margin="10,10,0,0" VerticalAlignment="Top" Width="400">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" Width="100" DisplayMemberBinding="{Binding ID}"/>
<GridViewColumn Header="Name" Width="190" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Delete" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="X" Width="30" Click="DeleteListItem"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListViewItem>
<local:User ID="1" Name="John" />
</ListViewItem>
<ListViewItem>
<local:User ID="2" Name="Michael" />
</ListViewItem>
<ListViewItem>
<local:User ID="3" Name="Smith" />
</ListViewItem>
<ListViewItem>
<local:User ID="4" Name="Mary" />
</ListViewItem>
</ListView>

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

DataTrigger is not firing

I have array of class Person in ViewModel and I want to show their names in table. I have also column with checkboxes. This is my View part:
<Grid>
<Grid.Resources>
<Style x:Key="CheckBoxStyle" TargetType="{x:Type Control}">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelectionAllowed}" Value="False">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<ListView ItemsSource="{Binding Persons}">
<ListView.View>
<GridView>
<GridViewColumn Width="40">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{StaticResource CheckBoxStyle}"
.........................
.... some logic here ....
......................./>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="140"
Header="Number"
DisplayMemberBinding="{Binding Path=Name}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
I want to show/hide checkboxes according to value of IsSelectionAllowed boolean variable. Why DataTrigger is not firing?
Assuming IsSelectionAllowed is a property on the view model set on the data context, you will need a relative source binding - hopefully this is correct without any testing:
<DataTrigger Binding="{Binding Path=IsSelectionAllowed, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" Value="False">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
The binding of IsSelectionAllowed in your code is to the Person type.

Categories