Selecting item in a virtualized XAML ListView throws an StackOverflow - c#

I have this XAML form with a virtualized ListView to show a grid:
<Window x:Class="WpfVirtualList.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="lvStyle" TargetType="{x:Type ListView}">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding}"/>
<Setter Property="ListView.View">
<Setter.Value>
<GridView>
<GridViewColumn Header="Cups" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CUPS}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="MeterId" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding MeterID}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Matricula" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding MatriculaCT}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoading}" Value="True">
<Setter Property="ListView.Cursor" Value="Wait"/>
<Setter Property="ListView.Background" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ListView x:Name="lv" HorizontalContentAlignment="Stretch" Style="{DynamicResource lvStyle}" SelectionChanged="lv_SelectionChanged" />
</Grid>
</Window>
And when I select an item everything works OK...
But when I select a second item the system throws an StackOverflow... and I don't know why.
I have breakpoints in all the virtual list methods, but no one of them are called when I click on the second item.
I have a breakpoint in SelectionChanged event, and isn't called either.
//CUPS is the id
private void lv_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(e.RemovedItems.Count > 0)
Debug.WriteLine("selected: "+((ItemClass)e.RemovedItems[0]).CUPS);
if(e.AddedItems.Count > 0)
Debug.WriteLine("unselected: " + ((ItemClass)e.AddedItems[0]).CUPS);
}
I fixed it controlling the GotFocus event and unselecting all... but this is not the way to solve this.
private void lv_GotFocus(object sender, RoutedEventArgs e)
{
lv.UnselectAll();
}

Related

WPF bind property of current ListView row

I am trying to implement a TreeView inside my ListView.
I would like the backgroud of my TreeBox would be the same as its "Father" row.
I guess there is a possibility to bind its BackGround property to its row's BackGround property, but how to do that?
Here is an image to explain the issue :
1st line is selected
2nd line is Over
I also put my XAML, in case that would help :
<ListView x:Name="ListView4" SelectedItem="{Binding SelectedRepere}" ItemsSource="{Binding ListeDesReperes}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4" MouseDoubleClick="ListView_MouseDoubleClick" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler" ContextMenuOpening="ListView4_ContextMenuOpening" SelectionChanged="ListView4_SelectionChanged" Visibility="{Binding Grid4Visible, Converter={StaticResource BoolToVisConverter}}" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsUniqueGeometry}" Value="true">
<Setter Property="FontWeight" Value="Bold" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.ContextMenu>
<ContextMenu x:Name="Context4">
<MenuItem x:Name="Context4MakeLonger" Header="{x:Static p:Resources.MakeLonger}" Click="Make_Longer"/>
<MenuItem x:Name="Context4Distinguer" Header="{x:Static p:Resources.DistributeToAss}" Click="DistinguerDetailRepere"/>
<MenuItem x:Name="Context4Search" Header="{x:Static p:Resources.Search}" Click="Search_Detail"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.View>
<GridView AllowsColumnReorder="true" x:Name="GridView4">
<GridViewColumn DisplayMemberBinding="{Binding Path=ID}" Header="ID" Width="200"/>
<GridViewColumn Header="Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TreeView BorderThickness="0" x:Name="treeviewList" ItemsSource="{Binding RepereTree}" Width="Auto">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<DataTemplate>
<TreeViewItem ItemsSource="{Binding ListeSubReperes}">
<TreeViewItem.Header>
<Grid>
<TextBlock Foreground="#FF042271" Text="{Binding NameOri}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0" Tag="{Binding Name}" MouseMove="mouseOverNameRepere" ToolTip="{Binding Path=ToolTipModifications}" MouseDown="TreeView_Main_Click"/>
</Grid>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<Grid Margin="-20,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Foreground="#FF042271" Text="{Binding Name}" Tag="{Binding IdRepereOri}" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0"MouseDown="TreeView_Sub_Click"/>
</Grid>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...
Edit :
Finally, putting "transparent doesn't completely solve the proble, sometimes it works, but sometimes when selecting the Treeview, it seems it gets selected, and I have the following result :
Then when I unselect it, it gives that result :
I would like the Treeview would be as any element of my row, for this the only way I found is add on each TextBlock a MouseDown event, then I do this :
private void TreeView_Main_Click(object sender, MouseButtonEventArgs e)
{
TextBlock item = (TextBlock)sender;
string name = (string)item.Text;
Repere rep = contexte.ListeDesReperes.FirstOrDefault(x => x.Name == name);
if (rep != null)
{
contexte.SelectedRepere = rep;
}
}
private void TreeView_Sub_Click(object sender, MouseButtonEventArgs e)
{
TextBlock item = (TextBlock)sender;
long idOri = (long)item.Tag;
Repere rep = contexte.ListeDesReperes.FirstOrDefault(x => x.ID==idOri);
if (rep != null)
{
contexte.SelectedRepere = rep;
}
}
Don't know if there is an easier way to do that, but that's all what I found until now.
Try to set the Background property of the TreeView to Transparent:
<TreeView Background="Transparent">
I put it here for who would come here :
how to change highlight values
Here it is well explained what are SystemColors parameters, on the end just had to add :
<TreeView.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey }" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</TreeView.Resources>

Style not taken in account on GridViewColumn ToolTip

So I have the following problem :
In my ListView, I want to add ToolTips to specific GridViewColumns.
Sometimes these ToolTips are empty, and I need to hide them.
When I have a ToolTip on a ListView Line, I encounter no problem doing the following in my App.xaml file:
<Style TargetType="ToolTip">
<Style.Triggers>
<Trigger Property="Content" Value="{x:Static sys:String.Empty}">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="Content" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
</Style.Triggers>
</Style>
But in the case a ToolTip is applied to only one column of my ListView, my XAML is the following :
<GridViewColumn Header="{x:Static p:Resources.Name}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=Name}" Tag="{Binding Name}"
MouseMove="mouseOverNameRepere">
<TextBlock.ToolTip>
<StackPanel>
<Grid>
<TextBlock Grid.Column="0"
Text="{Binding Path=ToolTipModifications}"
TextAlignment="Left" HorizontalAlignment="Left"/>
</Grid>
</StackPanel>
</TextBlock.ToolTip>
</TextBlock>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
How can I hide the ToolTip when it is empty? The code in my App.xaml is not working.
Also tried to do it in code behind :
TextBlock item = (TextBlock)sender;
ToolTip toolTip = (ToolTip)item.ToolTip;
But second line gives me an exception as item.ToolTip is a StackPanel object and cannot be converted?
In fact I calculate the ToolTip content only when I enter the TextBox element, so I thought I would then check and apply toolTip.Visibility at this moment, but I couldn't.
Your Style should work if you set the ToolTip property of the TextBlock like this:
<TextBlock Text="{Binding Path=Name}" Tag="{Binding Name}" MouseMove="mouseOverNameRepere"
ToolTip="{Binding Path=ToolTipModifications}" />
Use Rectangle instead of Tooltip
<GridViewColumn Header="{x:Static p:Resources.Name}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=Name}" Tag="{Binding Name}"/>
<Rectangle Fill="Transparent" ToolTipService.ToolTip="{Binding Path=ToolTipModifications}" MouseEnter="UIElement_OnMouseEnter"/>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Then check if ToolTipModifications is empty in MouseEnter event
private void UIElement_OnMouseEnter(object sender, MouseEventArgs e)
{
if (sender is Rectangle rectangle)
{
if (string.IsNullOrEmpty(rectangle.ToolTip.ToString()))
{
rectangle.Visibility = Visibility.Collapsed;
}
}
}
Please try this code:
<DataGridTextColumn Width="200" Binding="{Binding Name}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource TextBlockDefaultStyle}">
<Setter Property="ToolTip" Value="{Binding Name}">
<Setter Property="ToolTipService.ShowDuration" Value="6000">
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

C# XAML Master Detail Binding does not work

I want to display a List in a ListView with Master Detail View. The Master View works fine, but the binding to the detail view is not working. What am i doing wrong?
Code Behind:
DataContext = new VirtualizingCollection<LinesSummary>(fs, 100)
LinesSummary Class:
public class LinesSummary {
public string dateString { get; set; }
}
XAML:
<StackPanel>
<ListView Margin="5" Style="{DynamicResource lvStyle}" Height="200" x:Name="Master"/>
<ListView Margin="5" Style="{DynamicResource lvStyle_Detail}" Height="200" x:Name="Detail"/>
</StackPanel>
Dynamic Resource for Master View:
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding}"/>
<Setter Property="ListView.View">
<Setter.Value>
<GridView>
<GridViewColumn Header="Date" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding dateString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</Setter.Value>
</Setter>
</Style>
Dynamic Resource for Detail View:
<Style x:Key="lvStyle_Detail" TargetType="{x:Type ListView}">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding ElementName=Master, Path=SelectedItem.LinesSummary}"/>
<Setter Property="ListView.View">
<Setter.Value>
<GridView>
<GridViewColumn Header="aaa" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding dateString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</Setter.Value>
</Setter>
</Style>
The ItemsSource of a ListView can only be bound to an IEnumerable so even if you bind the ItemsSource property of the second ListView like this it won't work:
ItemsSource="{Binding ElementName=Master, Path=SelectedItem}"
...because LinesSummary is not an IEnumerable.
Since there is only a maximum of one item selected in Master, you might as well bind a TextBlock to the dateString property of its SelectedItem:
<StackPanel>
<ListView Margin="5" Style="{DynamicResource lvStyle}" Height="200" x:Name="Master"/>
<ListView Margin="5" Style="{DynamicResource lvStyle_Detail}" Height="200" x:Name="Detail">
<ListViewItem>
<TextBlock Text="{Binding Path=SelectedItem.dateString, ElementName=Master}" />
</ListViewItem>
</ListView>
</StackPanel>
Remove this setter from the lvStyle_Detail:
<Setter Property="ListView.ItemsSource" Value="{Binding ElementName=Master, Path=SelectedItem.LinesSummary}"/>

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>

WPF - Listview Item Margin

My Listview items are not stretching to the full width of the column. There is always a margin on the right of my cell border. I would like to get the bordered area to stretch over the full column width and get rid of any padding, margins or anything else on the left and right of my content. The goal is to have the borders fill the whole space in each cell.
I have already applied stretching and set the margins to "-6,0,-6,0" but that doesn't seem to solve the problem.
Here is my code:
<Grid>
<Grid.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="items">
<sys:String>Foo</sys:String>
<sys:String>Bar</sys:String>
<sys:String>Spong</sys:String>
</x:Array>
</Grid.Resources>
<ListView ItemsSource="{StaticResource items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin"
Value="-6, 0,-6,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Data" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border BorderThickness="2" BorderBrush="Black" HorizontalAlignment="Stretch">
<TextBox Text="{Binding .}" />
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Length"
DisplayMemberBinding="{Binding Length}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
I got it working using a DataTemplate resource and setting the border's margin to -6.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="items">
<sys:String>Foo</sys:String>
<sys:String>Bar</sys:String>
<sys:String>Spong</sys:String>
</x:Array>
<DataTemplate x:Key="MyDataTemplate">
<Border BorderThickness="2" BorderBrush="Black" Margin="-6">
<TextBox Text="{Binding .}" Margin="0" Padding="0"/>
</Border>
</DataTemplate>
</Grid.Resources>
<ListView ItemsSource="{StaticResource items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView >
<GridViewColumn Header="Data" Width="80" CellTemplate="{StaticResource MyDataTemplate}" />
<GridViewColumn Header="Length" DisplayMemberBinding="{Binding Length}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Just set the Margin for your Border element:
<Border Margin="-6,0,-6,0" BorderThickness="2" BorderBrush="Black" HorizontalAlignment="Stretch">
<TextBox Text="{Binding .}" />
</Border>
Alternative solution
typeof(GridViewRowPresenter).GetField("_defalutCellMargin", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.GetField).SetValue(null, new Thickness(0));
I do it with
HorizontalContentAlignment="Stretch"
on ListView

Categories