WPF - Listview Item Margin - c#

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

Related

How to Right-align the data in listView (no header) in wpf?

I have 1 listview with 1 column and no header, how the data is displayed to the right of the column, I have referenced this here, but it is ineffective in my project (sorry my english is not very good). Here is the my xaml code :
<Window x:Class="ListViewWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ListViewWPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Window.Resources>
<Style x:Key="RedTextBoxStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="true">
<Setter Property="Background" Value="RosyBrown"/>
<Setter Property="IsReadOnly" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition ></ColumnDefinition>
<ColumnDefinition ></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ListView ItemsSource="{Binding Mydata}" SelectedItem="{Binding seleItems}" Grid.RowSpan="3" Grid.ColumnSpan="2">
<ListView.Resources>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value1}" TextAlignment="Right"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Grid.Row="0" Grid.Column="2" Margin="20" Content="1" FontSize="25"></Button>
<Button Grid.Row="1" Grid.Column="2" Margin="20" Content="2" FontSize="25"></Button>
</Grid>
</Window>
I hope to receive your comments!
Ironically, there's a whole MSDN article on this subject - How to: Change the Horizontal Alignment of a Column in a ListView - and yet they leave out a very important piece of information.
If you take a look at the doc on GridViewColumn.Width, you'll see two important things:
It's a double, not a GridLength (so no star sizing)
This quote:
The default is NaN, which automatically sizes to the largest column item that is not the column header.
So even though your items are stetching to fill the column, your column is only as wide as your longest item, not the width of the whole ListView.
Now, you could do something like in this answer with code, or you would try binding to ListView.ActualWidth, but really, there's a much simpler solution:
Simple Solution: Just use ListBox instead.
<ListBox ItemsSource="{Binding Mydata}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value1}" HorizontalAlignment="Right"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
A ListBox is very similar- if not identical- to a single-column ListView with no header. Except the items will actually size the way you want them to.

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>

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}"/>

Is an XAML file portable to Xamarin Macintosh?

I don't have access to a Macintosh to test this on (i.e, I can't load the Xamarin Mac components) so I don't have a way to test this. But...below is the XAML of a WPF app. Most everything in the app appears to be Xamarin-compliant -- WebClient calls, populating my form fields through an XMLDocument and binding, for instance -- but I don't know of the XAML is compliant. So, here it is:
<Window x:Class="IMManager.ImManagerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="IMM Media Manager"
SnapsToDevicePixels="True"
WindowState="Normal"
MaxWidth="720"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<Style x:Key="AlternatingListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<!-- setting up triggers for alternate background colors -->
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="White"></Setter>
</Trigger>
</Style.Triggers>
<!-- setting row height here -->
<Setter Property="Height" Value="25" />
</Style>
</Window.Resources>
<ListView x:Name="LvAlbums" ItemsSource="{Binding XPath=/downloads/Album}" Width="680">
<ListView.ItemTemplate>
<DataTemplate x:Name="dt1">
<StackPanel x:Name="spAlbum" HorizontalAlignment="Left">
<TextBlock
Text="{Binding XPath=#Artist,StringFormat='Artist: {0}'}"
FontSize="16px"
/>
<TextBlock
Text="{Binding XPath=#Name,StringFormat='Album: {0}'}"
FontSize="16px"
/>
<ListView x:Name="lvTracks" ItemsSource="{Binding XPath=Item}" ItemContainerStyle="{StaticResource AlternatingListViewItemStyle}" AlternationCount="2">
<ListView.View>
<GridView>
<GridViewColumn Header="Track" Width="460">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="trackName" Text="{Binding XPath=#Name}" Width="450" LineHeight="25" Height="25" VerticalAlignment="Center" Margin="0,3,0,0">
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Progress" Width="175">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Canvas VerticalAlignment="Center" Height="25">
<ProgressBar Foreground="GreenYellow" Name="PbStatus" Value="{Binding XPath=#Progress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="0" Maximum="100" Height="20" VerticalAlignment="Center" Margin="0,3,0,0" Width="165"/>
<TextBlock FontFamily="Segoe UI" LineHeight="25" FontWeight="Bold" Text="{Binding XPath=#Info, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Height="20" Width="165" VerticalAlignment="Center" Margin="0,4,0,0"/>
</Canvas>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Can Mac Xamarin handle this or something close to this?
No. Xamarin Mac does not use XAML. Xamarin Forms does, but it is a different syntax than the XAML used in WPF.

Datatemplates while using theme does not work - WPF

I am using the theme DarkExpression from WPF Futures.
It does not seem to work well with datatemplates.
Scenario 1:
Here is how it looks like without datatemplates:
Code:
<ListView Name="playlistListView" ItemsSource="{Binding PlaylistList}" Margin="0" SelectionChanged="DatabindedPlaylistListView_SelectionChanged" Background="{x:Null}" Opacity="0.98">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Name}">
<GridViewColumnHeader HorizontalContentAlignment="Left" Content="Playlist" Tag="Playlist"/>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Scenario 2:
Here is how it looks like trying to use datatemplates while using the theme:
Code:
<ListView Name="playlistListView" ItemsSource="{Binding PlaylistList}" Margin="0" SelectionChanged="DatabindedPlaylistListView_SelectionChanged" Background="{x:Null}" Opacity="0.98">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<UserControls:SongDataTemplate Margin="4" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Scenario 3:
Here is how it looks like trying to use datatemplates while overriding the theme:
Code:
<UserControl.Resources>
<Style x:Key="ListViewItemStretch" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent" />
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<ListView Name="playlistListView" ItemContainerStyle="{StaticResource ListViewItemStretch}" ItemsSource="{Binding PlaylistList}" Margin="0" SelectionChanged="DatabindedPlaylistListView_SelectionChanged" Background="{x:Null}" Opacity="0.98">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<UserControls:SongDataTemplate Margin="4" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I want to keep the theme style but I also want to use datatemplates to define how a playlist should look like. Any suggestions?
Note: In scenario 2 and 3 I had to remove
<ListView.View>
<GridView>
<GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Name}">
<GridViewColumnHeader HorizontalContentAlignment="Left" Content="Playlist" Tag="Playlist"/>
</GridViewColumn>
</GridView>
</ListView.View>
Before the datatemplate would be used.
Edit:
The solution given below, works if the type is changed to ListBox and I am using a TextBox instead. I can't however make it work with a ListView.
You are doing it wrong.
When you want to customize ListView you need to work with the View property which is of type ViewBase. Derive a custom View from ViewBase, assign it to ListView.View and you're done.
There's an example in ViewBase Class Documentation
Try by using BasedOn
<Style BasedOn={StaticResource {x:Type ListViewItem}} x:Key="ListViewItemStretch" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent" />
</Style>
does it work if you substitute
<Grid>
<UserControls:SongDataTemplate Margin="4" />
</Grid>
with a TextBox, for example?
The problem could be generated by your user control..

Categories