WPF how to detect listviewitem has been selected - c#

I have DataTemplate for my ListView control, which contains few textblocks and a button. I want the button to be visible only when the item is selected.
Here's my DataTemplate code:
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="AliceBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="90" />
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left" Margin="10,0,10,0"
VerticalAlignment="Center" FontFamily="Verdana" FontSize="16"
FontWeight="Black" Grid.Column="0" Text="{Binding name}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Column="1">
<TextBlock FontFamily="Verdana" FontSize="10" Grid.Column="1"
VerticalAlignment="Center" HorizontalAlignment="Center"
Text="Number of Chapters: " />
<TextBlock FontFamily="Verdana" FontSize="12" Grid.Column="1"
VerticalAlignment="Center" HorizontalAlignment="Center"
Text="{Binding chaptersCount}" />
</StackPanel>
<Button HorizontalAlignment="Center" Height="50" Width="80" Content="Read"
Grid.Column="2" Visibility="Hidden" Click="Button_Click_3" Name="ReadButton"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
How can I do that?

You can achieve this with DataTrigger in DataTemplate which will check for IsSelected property of Templated parent:
<ListView.ItemTemplate>
<DataTemplate>
.....
<Button HorizontalAlignment="Center" Height="50"
Width="80" Content="Read"
Grid.Column="2" Visibility="Hidden" Name="ReadButton"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected,
RelativeSource={RelativeSource Mode=TemplatedParent}}"
Value="True">
<Setter TargetName="ReadButton" Property="Visibility"
Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>

You need to slightly change your Button: A quick XAML way would be to add a Trigger on its Visibility to make it hidden when not selected (note: code written here, hopefully there's no typo):
<Button HorizontalAlignment="Center" Height="50" Width="80" Content="Read"
Grid.Column="2" Click="Button_Click_3" Name="ReadButton">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}" Value="False">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

Related

WPF C# Datagrid change last row layout

I have a datagrid where I show values about the beginning and the end of a period. For that I created a column template with 2 textblocks, but in the last row I show a diference between these values as percentage. What I want to do is to centerlize the first text block in the last row as I have only one value in that row.
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Officer11Nome}"
HorizontalAlignment="Center"
Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="3"
/>
<TextBlock Text="Abertura"
HorizontalAlignment="Center"
Grid.Column="0"
Grid.Row="1"
/>
<TextBlock Text="Fechamento"
HorizontalAlignment="Center"
Grid.Column="2"
Grid.Row="1"
/>
</Grid>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Officer1Abertura}" Margin="2,0,2,0" TextAlignment="Left" Grid.Column="0"/>
<TextBlock Text="{Binding Officer1Fechamento}" Margin="2,0,2,0" TextAlignment="Right" Grid.Column="2"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Thanks.
This is workaround playing with trigger
(1) Create third property . When its shown the other two will not be shown. Keep it null till the time its not calculated. for the time being i name it as differencofvalues. Give appropriate name and bind
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Name="textbox1" Text="{Binding Officer1Abertura}" Margin="2,0,0,0" TextAlignment="Center" Width="Auto" />
<TextBlock Text="{Binding differenceOfValues}" Margin="0,0,0,0" TextAlignment="Center" Width="Auto">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding differenceOfValues}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"></Setter>
<Setter Property="{Binding ElementName=textbox1, Path=Visibility}" Value="Visible"></Setter>
<Setter Property="{Binding ElementName=textbox2, Path=Visibility}" Value="Visible"></Setter>
</DataTrigger>
<Trigger Property="Visibility" Value="Visible">
<Setter Property="{Binding ElementName=textbox1, Path=Visibility}" Value="Collapsed"></Setter>
<Setter Property="{Binding ElementName=textbox2, Path=Visibility}" Value="Collapsed"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Name="textbox2" Text="{Binding Officer1Fechamento}" Margin="10,0,2,0" TextAlignment="Center" Width="Auto" Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
I created another property with the configurations that I needed. Since I dont have values in the others properties it fits well.
<TextBlock Text="{Binding Officer1Percentagem}" TextAlignment="Center" Grid.Column="0" Grid.ColumnSpan="3"/>
<TextBlock Text="{Binding Officer1Abertura}" TextAlignment="Right" Grid.Column="0"/>
<TextBlock Text="{Binding Officer1Fechamento}" TextAlignment="Right" Grid.Column="2"/>

WPF Add more interaction to listview items

I am binding my listview to a viewmodel using Caliburn. My view's code is the following:
<ListView x:Name="ListView" Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding ProjectsPMod}" Margin="110,0,110,131" HorizontalContentAlignment="Stretch" BorderThickness="0" Height="111" VerticalAlignment="Bottom">
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="SelectionChanged">
<cal:ActionMessage MethodName="OpenProjectShell">
<cal:Parameter Value="{Binding ElementName=ListView, Path=SelectedItem}" />
</cal:ActionMessage>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal">
<ContentControl Content="{StaticResource Appbar_Suitcase}" />
<Label Content="{Binding Name}"/>
</StackPanel>
<Separator HorizontalAlignment="Stretch" Margin="0, 10, 0, 0"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Right now each item in every row just displays its name and a briefcase icon. If I wanted to add an "Edit"further down that row, where if you clicked on it something happened (perhaps a popup appears), how would I do it?
You can make an ordinary Button look like a link using a template. Just add a Button to your StackPanel and bind it to a command:
<ListView x:Name="ListView" Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding ProjectsPMod}" Margin="110,0,110,131" HorizontalContentAlignment="Stretch" BorderThickness="0" Height="111" VerticalAlignment="Bottom">
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="SelectionChanged">
<cal:ActionMessage MethodName="OpenProjectShell">
<cal:Parameter Value="{Binding ElementName=ListView, Path=SelectedItem}" />
</cal:ActionMessage>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal">
<ContentControl Content="{StaticResource Appbar_Suitcase}" />
<Label Content="{Binding Name}"/>
</StackPanel>
<Separator HorizontalAlignment="Stretch" Margin="0, 10, 0, 0"/>
<Button Margin="0 10 0 0" Content="Link" Cursor="Hand" Command="{Binding YourCommand}">
<Button.Template>
<ControlTemplate TargetType="Button">
<TextBlock TextDecorations="Underline">
<ContentPresenter />
</TextBlock>
</ControlTemplate>
</Button.Template>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Blue" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You can control the position of the Button within the StackPanel using its Margin property.
If you mean "How to add an edit button for each row?" then you simply need to add a button in the ItemTemplate:
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal">
<ContentControl Content="{StaticResource Appbar_Suitcase}" />
<Label Content="{Binding Name}"/>
<!-- Edit button -->
<Button Command="{Binding EditCommandOnViewModel}" Content="Edit" />
</StackPanel>
<Separator HorizontalAlignment="Stretch" Margin="0, 10, 0, 0"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>

WPF Еditable Textbox in a Listbox

I'm new to wpf, but even so I thought this is a trivial problem. So i have а listbox with 4 columns: file names, textbox, checkbox and a button. The buttons are working fine, but for some reason i can't use the textboxes - can't click them or write inside them.
Here is my xaml:
<ListBox Name="lbDocxFiles" HorizontalContentAlignment="Stretch" Margin="10,0" Grid.ColumnSpan="2" Grid.Row="2" SelectionChanged="lbDocxFiles_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBox" Grid.Column="3" Content="" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBox x:Name="tbNodeID" IsReadOnly="False" AcceptsReturn="True" IsEnabled="True" Focusable="True" TextWrapping="Wrap" HorizontalAlignment="Right" Height="25" Width="90" Text="" VerticalAlignment="Center" Grid.ColumnSpan="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="IsReadOnly" Value="False" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<Button Grid.Column="2" Width="70" Height="25" Content="UPLOAD" Click="btnUpload_Click" Background="#FF70ECD5" BorderThickness="0" Foreground="White" />
<TextBlock Grid.Column="0" Text="{Binding fileTitle}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
I guess i'm doing something wrong, but can't find out why the texboxes are not editable. Any help will be appreciated!
Thanks in advance!
Refer the below code. It should work. There some UI layout issue.
<ListBox x:Name="lbDocxFiles" HorizontalContentAlignment="Stretch" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="90" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<CheckBox x:Name="checkBox" Grid.Column="3" Content="Tets" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBox x:Name="tbNodeID" IsReadOnly="False" AcceptsReturn="True"
IsEnabled="True" Focusable="True" TextWrapping="Wrap" HorizontalAlignment="Right"
Height="25" Width="90" Text="" VerticalAlignment="Center" Grid.Column="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="IsReadOnly" Value="False" />
</Trigger>
<Trigger Property="IsFocused" Value="False">
<Setter Property="IsReadOnly" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<Button Grid.Column="2" Width="70" Height="25" Content="UPLOAD"
Background="#FF70ECD5" BorderThickness="0" Foreground="White" />
<TextBlock Grid.Column="0" Text="{Binding MyProperty}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ObservableCollection<MyModel> lst = new ObservableCollection<MyModel>();
lst.Add(new MyModel() { MyProperty = "Hi" });
lbDocxFiles.ItemsSource = lst;
}
}
class MyModel
{
private string myVar;
public string MyProperty
{
get { return myVar; }
set { myVar = value; }
}
}
So i found a solution here that works. We set the FocusManager.FocusedElement property in style trigger:
<Window.Resources>
<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<StackPanel FocusManager.FocusedElement="{Binding ElementName=MyTextBox}" Orientation="Horizontal">
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding fileTitle}" Grid.Column="0" />
<TextBox Name="tbNodeID" Text="{Binding Details}" Height="25" Width="90" HorizontalAlignment="Right" Grid.Column="2" />
<Button Grid.Column="1" Width="70" Height="25" HorizontalAlignment="Right" Content="UPLOAD" Click="btnUpload_Click" Background="#FF70ECD5" BorderThickness="0" Foreground="White" />
<CheckBox x:Name="checkBox" Grid.Column="3" Content="" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter TargetName="tbNodeID" Property="FocusManager.FocusedElement" Value="{Binding ElementName=tbNodeID}" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="tbNodeID" Property="FocusManager.FocusedElement" Value="{Binding ElementName=tbNodeID}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ListBox Name="myLB" SelectedIndex="{Binding MySelectedIndex}">
</ListBox> </Grid>
This not only makes my textbox editable, but also focus it when item from the listbox is clicked.

Listbox Separator in WPF and Omission of Final Separator

I have two things I'm trying to achieve:
Add a horizontal separator between listbox items in WPF.
Don't show the separator at the bottom of the final listbox item.
My current layout is pictured here:
This shows 2 listbox items (though I have no way of knowing how many items could potentially be generated). I would like them separated by a horizontal separator, except on the last listbox item so there isn't a spare separator at the bottom of the pane. How can I achieve this in XAML? See my current XAML here:
<TabItem Header="Third Party Updates">
<Grid>
<TextBlock Name="ThirdPartyNoManifestTextBox" Width="Auto" HorizontalAlignment="Left" Margin="267,22,0,0" TextWrapping="Wrap" Text="{Binding Path=WindowsUpdateCompliance, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" FontSize="14" Foreground="DarkSlateBlue"/>
<Button Name="CheckforThirdPartyUpdatesButton" Content="Check for Third Party Updates" Margin="10,11,339,304" Click="CheckforThirdPartyUpdatesButton_Click" MaxWidth="200" Grid.Column="1" Grid.Row="1"/>
<ListBox Name="ThirdPartyListBox" ItemsSource="{Binding}" Margin="0,70,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Name="ThirdPartyInstallButton" Content="Install" Click="InstallThirdPartyUpdatesButton_Click" Margin="5,5,0,0" Height="25"></Button>
<Button Name="ThirdPartyPostoneButton" Content="Postpone" Click ="PostponeThirdPartyUpdatesButton_Click" Margin="5,5,0,0" Height="25"></Button>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Content="•" Grid.Row="1" VerticalContentAlignment="Center"/>
<Label Content="•" Grid.Row="2" VerticalContentAlignment="Center"/>
<Label Content="•" Grid.Row="3" VerticalContentAlignment="Center"/>
<Label Content="•" Grid.Row="4" VerticalContentAlignment="Center"/>
<StackPanel Orientation="Horizontal" Grid.Column="1">
<Label Name="MissingRequiredAppGenericTextBlock" VerticalAlignment="Center" Content="Required application update detected:" FontWeight="SemiBold" FontSize="12"/>
<Label Name="RequiredAppNameTextBlock" VerticalAlignment="Center" Content="{Binding Item2.Name}" Foreground="MidnightBlue" FontSize="13"/>
<Label Grid.Column="1" Grid.Row="1" Name="RequiredAppVersionTextBlock" Content="{Binding Item2.RequiredVersion}" VerticalAlignment="Center" Foreground="MidnightBlue" FontSize="13"/>
</StackPanel>
<TextBlock Grid.Column="1" Grid.Row="1" Name="RequiredAppCustomUIMessageTextBlock" Text="{Binding Item2.CustomUIMessage}" TextWrapping="Wrap" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Grid.Row="2" VerticalAlignment="Center">
<Hyperlink Name="Link" NavigateUri="{Binding Item2.TT}" RequestNavigate="Hyperlink_RequestNavigate">
<TextBlock Text="{Binding Item2.TT}"/>
</Hyperlink>
</TextBlock>
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="3">
<TextBlock Text="The following processes will be closed prior to install: " VerticalAlignment="Center" />
<TextBlock Text="{Binding Item2.ListOfProcessesToClose}" FontWeight="SemiBold" Foreground="Red" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="4">
<TextBlock Text="You have used " VerticalAlignment="Center" />
<TextBlock Text="{Binding Item3.UsedDeferrals}" VerticalAlignment="Center"/>
<TextBlock Text=" of " VerticalAlignment="Center"/>
<TextBlock Text="{Binding Item2.MaxDefferals}" VerticalAlignment="Center"/>
<TextBlock Text=" deferrals for this update." VerticalAlignment="Center"/>
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding PostponeClicked}" Value="1">
<Setter Property="Visibility" Value="Hidden"></Setter>
</DataTrigger>
<Trigger Property="Control.IsMouseOver" Value="True">
<Setter Property="Control.BorderBrush" Value="SteelBlue" />
<Setter Property="Control.BorderThickness" Value="1" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</TabItem>
Update
Added suggested separator code. Separator is now present but does not fill the available horizontal space:
You can try to put Separator at the top of each item. With that you don't have unwanted Separator after the last item.
Then use DataTrigger with {RelativeSource PreviousData} binding to hide separator at the top of the first item :
<StackPanel>
<Separator>
<Separator.Style>
<Style TargetType="Separator">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Separator.Style>
</Separator>
<StackPanel Orientation="Horizontal">
<Button Name="ThirdPartyInstallButton" Content="Install" Click="InstallThirdPartyUpdatesButton_Click" Margin="5,5,0,0" Height="25"></Button>
<Button Name="ThirdPartyPostoneButton" Content="Postpone" Click ="PostponeThirdPartyUpdatesButton_Click" Margin="5,5,0,0" Height="25"></Button>
<Grid>
.........
.........
</Grid>
</StackPanel>
</StackPanel>
UPDATE :
I can't tell for sure what causes the separator not stretching accross listbox width. Maybe try to set listboxitem's HorizontalContentAlignment to Stretch :
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>

How to apply different styles to ListBox header and item

I have a ListBox which is bound to my custom class
ObservableCollection<FieldPropertyItem> _fieldOrderCollection`;
internal struct FieldPropertyItem
{
public string Name { get; set; }
public string AliasName { get; set; }
}
Code for ListBox:
<ListBox x:Name="FieldOrderListBox" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" SelectedIndex="0"
ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionChanged="FieldOrderListBox_SelectionChanged">
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#FF479EF3"></SolidColorBrush>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate x:Name="MyTemplate">
<Grid Margin="-5,-1,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="FieldName" MinWidth="5" MaxWidth="300"/>
<ColumnDefinition Width="2" />
<ColumnDefinition Width="*" MaxWidth="350"/>
</Grid.ColumnDefinitions>
<Border BorderBrush="Black" Grid.Column="0" BorderThickness="0.5,0.0,0.5,0.5" IsHitTestVisible="False">
<TextBlock Text="{Binding Name}" Grid.Column="0" ToolTip="{Binding Name}" Margin="2,0,2,0" VerticalAlignment="Center"/>
</Border>
<GridSplitter Grid.Column="1" Width="2" HorizontalAlignment="Left" Background="Black" Margin="-2,0,-1,0"/>
<Border BorderBrush="Black" BorderThickness="0,0.0,0.5,0.5" Margin="-2,0,0,0" Padding="0,5,0,0" Grid.Column="2">
<TextBlock Text="{Binding AliasName}" Grid.Column="1" ToolTip="{Binding AliasName}" Margin="2,0,2,0" VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Now i want that my ListBox first item should look like header. The remaining ones should have a light dim background.
You can check if the previous item is null using a RelativeSource binding in a trigger, e.g. this DataTemplate makes the first element bold:
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A" />
<ColumnDefinition SharedSizeGroup="B" />
</Grid.ColumnDefinitions>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
<Setter Property="TextElement.FontWeight" Value="Bold" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<TextBlock Grid.Column="0" Text="{Binding Name}" />
<TextBlock Grid.Column="1" Text="{Binding AliasName}" />
</Grid>
</DataTemplate>
(Use shared size groups as shown above to align the grids with one-another, set Grid.IsSharedSizeGroup to true on the ListBox element)
I would not recommend doing this by the way, if your item collection contains the header there is definitely something wrong with your data-design.
1.) You can have a new Property IsFirstItem on your FieldPropertyItem
Whenever your _fieldOrderCollection changes determine the IsFirtItem Property of the elements in your ObservableCollection.
2.) Define the corresponding Templates in XAML (Normal and FirstItem Template)
3.) You can then bind in XAML like this:
<ListBox ItemsSource="{Binding Items}" >
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl x:Name="contentControl" Content="{Binding}" ContentTemplate="{StaticResource normalTemplate}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsFirstItem}" Value="True" >
<Setter TargetName="contentControl" Property="ContentTemplate" Value="{StaticResource firstItemTemplate}"></Setter>
</DataTrigger>
</DataTemplate.Triggers>
</ListBox.ItemTemplate>
</ListBox>

Categories