How to add spacing between the listview.items? - wpf

I would like to add distance between its items, so I can lead my bind operation on it.
<ListView Margin="0,22,0,0" x:Name="ListViewImages" MouseLeftButtonDown="ListViewImages_MouseLeftButtonDown"
SelectionMode="Extended" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled" local:ListBoxExtention.IsRectSelectionEnabled="True">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Name="WraPanel1" Margin="5" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="5" ></RowDefinition>
<RowDefinition Height="150"></RowDefinition>
<RowDefinition Height="15" ></RowDefinition>
<RowDefinition Height="5" ></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7" x:Name="columnLeft"></ColumnDefinition>
<ColumnDefinition Width="100" x:Name="columnImage"></ColumnDefinition>
<ColumnDefinition Width="7" x:Name="columnRight"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Name="Grid_Images" AllowDrop="True" Width="Auto" Height="Auto" Tag="{Binding Id}" Source="{Binding Converter={StaticResource imageConverter}}" Grid.Row="1" Grid.Column="1"
DragEnter="Grid_Images_DragEnter" MouseLeftButtonDown="Grid_Images_MouseLeftButtonDown" MouseLeftButtonUp="Grid_Images_MouseLeftButtonUp"
MouseMove="Grid_Images_MouseMove" Drop="Grid_Images_Drop" KeyUp="Grid_Images_KeyUp" />
<TextBlock Name="Grid_Descrition" AllowDrop="True" TextAlignment="Center" Text="{Binding Id}" Grid.Row="2" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Hopefully this will save someone else time. I found there are multiple properties that have to be set to 0 in order to completely remove the spacing between ListViewItems in a ListView control. In addition to Margin and Padding I had to set the BorderThickness to 0.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListView.ItemContainerStyle>

You can just add some Margin to your grid
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="5" ></RowDefinition>
<RowDefinition Height="150"></RowDefinition>
<RowDefinition Height="15" ></RowDefinition>
<RowDefinition Height="5" ></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7" x:Name="columnLeft"></ColumnDefinition>
<ColumnDefinition Width="100" x:Name="columnImage"></ColumnDefinition>
<ColumnDefinition Width="7" x:Name="columnRight"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Name="Grid_Images" AllowDrop="True" Width="Auto" Height="Auto" Tag="{Binding Id}" Source="{Binding Converter={StaticResource imageConverter}}" Grid.Row="1" Grid.Column="1"
DragEnter="Grid_Images_DragEnter" MouseLeftButtonDown="Grid_Images_MouseLeftButtonDown" MouseLeftButtonUp="Grid_Images_MouseLeftButtonUp"
MouseMove="Grid_Images_MouseMove" Drop="Grid_Images_Drop" KeyUp="Grid_Images_KeyUp" />
<TextBlock Name="Grid_Descrition" AllowDrop="True" TextAlignment="Center" Text="{Binding Id}" Grid.Row="2" Grid.Column="1"/>
</Grid>

Add a ListView.ItemContainerStyle and create a Setter that applies a Margin of whatever size you prefer.

Related

Can't get Xaml TextBlock TextWrapping to work

My code is pretty straightforward:
<ListView Grid.Row="0" ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<Border Grid.Row="0" Margin="0 2 0 2" BorderBrush="Black" BorderThickness="1" x:Name="ListItem" >
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Title}" FontWeight="Bold" FontSize="18" />
<Image Grid.Row="0" Grid.Column="1" Source="../Images/x.png" HorizontalAlignment="Right"/>
<StackPanel Orientation="Vertical" Grid.Row="1" Grid.ColumnSpan="2" MaxWidth="{Binding ElementName=ListItem, Path=Width}">
<TextBlock TextWrapping="WrapWithOverflow" Text="{Binding Description}" />
</StackPanel>
<TextBlock Grid.Row="2" Grid.ColumnSpan="2" Text="{Binding TimeStamp}" HorizontalAlignment="Right"/>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
But the listview width becomes bigger than window's width every times there's an item with long descriptions
Neither the HorizontalContentAlignment setter, nor TextWrapping or MaxWitdh work.
What am I doing wrong??
Disable horizontal scrolling:
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" ...>

Use HeaderedItemsControl in Datagridcell not showing Content

I want to disply a HeaderedItemsControlin a DataGridTemplateColumn. However, the following code only shows the header, but not the content. Where did I go wrong?
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<HeaderedItemsControl ItemsSource="{Binding Days[0].Employee}">
<HeaderedItemsControl.Template>
<ControlTemplate TargetType="HeaderedItemsControl">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Employee"/>
<Button Grid.Column="1"></Button>
</Grid>
</ControlTemplate>
</HeaderedItemsControl.Template>
<HeaderedItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</HeaderedItemsControl.ItemsPanel>
<HeaderedItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</HeaderedItemsControl.ItemTemplate>
</HeaderedItemsControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
You forgot to include ItemsPresenter in your Template. So your control has only header, nothing else. Just adding it back will do the trick:
<ControlTemplate TargetType="HeaderedItemsControl">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="22" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="Employee" />
<Button Grid.Column="1" />
<ItemsPresenter Grid.Row="1" Grid.ColumnSpan="2" />
</Grid>
</ControlTemplate>
Also, are you sure Days[0].Employee is a collection? It looks strange for sure.
As a bonus, you don't really have to use HeaderedItemsTemplate. Your template is simple enough to make it with basic controls:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="24" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<TextBlock Text="Employee" />
<Button Grid.Column="1" />
<ItemsControl ItemsSource="{Binding Days[0].Employee}" Grid.Row="1" Grid.ColumnSpan="2">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Set TextBlock width to 100% inside DataTemplate in Windows Store app

I have this XAML and having problems with grid width.
<DataTemplate x:Key="FormTileItemTemplate">
<Grid Height="70" Background="#FFECECEC">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="38" />
</Grid.ColumnDefinitions>
<StackPanel Margin="10,0,20,15" VerticalAlignment="Bottom">
<TextBlock Text="{Binding FormName}" Foreground="Black" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="0" FontSize="34.667" FontWeight="Light" LineHeight="32" />
</StackPanel>
<Grid Grid.Column="1">
<Image Stretch="UniformToFill" Source="/Assets/Images/FormCompleteRed.png" />
</Grid>
</Grid>
</DataTemplate>
<Grid x:Name="itemFormsGrid" Margin="0,60,0,50">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Margin="0,0,20,0" Width="100" Height="100" Source="/Assets/Images/session-forms.png" Stretch="UniformToFill" HorizontalAlignment="Right" />
<ListView
x:Name="formListView"
Grid.Row="1"
IsSwipeEnabled="False"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource FormTileItemTemplate}"
d:DataContext="{Binding Path=SessionForms, Source={d:DesignInstance Type=SampleData:SessionReviewDesignDataSource, IsDesignTimeCreatable=True} }"
Margin="0,20,0,0" />
</Grid>
Here is the output. Output
But I need the TextBlock to stretch way up to right. Appreciate any help.
Set HorizontalContentAlignment property like below to stretch the ListViewItems
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>

User control inside ScrollViewer doesn't scroll in WPF

I have the following code (abbreviated) in my main window:
Although I set both scroll bar visibilities and CanContentScroll properties it doesn't scroll. I assume it has to do with my user control.
<Window>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TabControl Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" Margin="0" VerticalAlignment="Stretch" Height="Auto" Width="Auto">
<TabItem Header="TEST">
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<my:MY_USER_CONTROL x:Name="myUserControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.CanContentScroll="True" />
</ScrollViewer>
</TabItem>
</TabControl>
<Button Grid.Column="0" Grid.Row="2" >a button</Button>
<WrapPanel Grid.Column="0" Grid.Row="3" >
</WrapPanel>
</Grid>
</Window>
Abbreviated structure of my user control:
<UserControl>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="183*" />
<ColumnDefinition Width="117*" />
</Grid.ColumnDefinitions>
<TreeView ItemsSource="{Binding Children}" Grid.ColumnSpan="2">
<TreeView.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>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.Children>
<TextBlock Background="LightGray" Padding="2" Margin="2" Grid.Row="0" Grid.Column="0" Text="{Binding Name}" />
<TextBlock Padding="2" Margin="2" Grid.Row="0" Grid.Column="1" Text="{Binding Content}" />
</Grid.Children>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</UserControl>
You need to set it like this. I changed the RowDefinition for Row0 to Height="*" So it will use as much space it can. Then changed place between the ScrollViewer and the TabControl. So the TabControl is a content of the ScrollViewer.
<Window>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Grid.Column="0" Grid.Row="0">
<TabControl HorizontalAlignment="Stretch" Margin="0" VerticalAlignment="Stretch"
Height="Auto" Width="Auto">
<TabItem Header="TEST">
<my:MY_USER_CONTROL x:Name="myUserControl"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ScrollViewer.CanContentScroll="True" />
</TabItem>
</TabControl>
</ScrollViewer>
<Button Grid.Column="0" Grid.Row="2" >a button</Button>
<WrapPanel Grid.Column="0" Grid.Row="3" >
</WrapPanel>
</Grid>
When you set CanContentScroll to True, the ScrollViewer assumes that your content implements IScrollInfo (which i guess doesn´t).
Try setting CanContentScroll on the ScrollViewer to false, this allows the content to use as much space as it wants and the ScrollViewer takes care of scrolling.
However, depending on the size, number of visuals etc. of your control, this might become a performance issue (e.g. no UI Virtualization when CanContentScroll is set to False).
Looks like the content inside your scrollviewer is the same size as the viewer so there is nothing to scroll?
if you do something like
<ScrollViewer HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid Background="Red">
</Grid>
</ScrollViewer>
Then the grid is the same size as the scroll viewer and will never allow scrolling, if you set the height of the grid to more than the viewer can display you'll get a scroller.
<ScrollViewer HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid Background="Red" Height="500">
</Grid>
</ScrollViewer>

Style each datagrid column header

I want to add another row to the HeaderRow and for each column insert specific control.
This is my code where add this row, but I can only set same control (in this case textbox) for every column, but I want to set specific control for specific column.
(like it's done in ASP.NET repeater)
<Style x:Key="DataGridColumnHeaderStyle1" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid x:Name="grid" VerticalAlignment="Center" HorizontalAlignment="Stretch" Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="ColumnHeader" Grid.Row="0" Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Height="18" />
<Grid Grid.Row="1">
<TextBox Text="" HorizontalAlignment="Stretch" BorderThickness="0,1,1,1" />
</Grid>
</Grid>
</Style>
You can Make use of the HeaderTemplate to specify different datatemplates for each Column
Sample
<Window.Resources>
<DataTemplate x:Key="Template1">
<Grid x:Name="grid" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="ColumnHeader" Text="Student Id" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Height="18" />
<Grid Grid.Row="1">
<TextBox Text="" HorizontalAlignment="Stretch" BorderThickness="0,1,1,1" />
</Grid>
</Grid>
</DataTemplate>
<DataTemplate x:Key="Template2">
<Grid x:Name="grid" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="ColumnHeader" Text="Student Name" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Height="18" />
<Grid Grid.Row="1">
<TextBox Text="" HorizontalAlignment="Stretch" BorderThickness="0,1,1,1" />
</Grid>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<DataGrid Name="dataGrid" >
<DataGrid.Columns>
<DataGridTextColumn HeaderTemplate="{StaticResource Template1}" Width="90*" MinWidth="120" Binding="{Binding StudentId}"/>
<DataGridTextColumn HeaderTemplate="{StaticResource Template2}" Width="90*" MinWidth="120" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Score" Width="100*" MinWidth="150" Binding="{Binding Score}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
I approached this a little bit different, I styled DataGridColumnHeadersPresenter, it allows me to syle the column headers row (instead of column header).
There I add my new row and all the controls I need, I alsoe set the width of every cell to match the width of it's header .
<Style x:Key="DataGridColumnHeadersPresenterStyle1" TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DataGridColumnHeader x:Name="PART_FillerColumnHeader" IsHitTestVisible="False"/>
<ItemsPresenter/>
<Grid Grid.Row="1" VerticalAlignment="Top" HorizontalAlignment="Left" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=Col1}"/>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=Col2}"/>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=Col3}"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Bottom" Width="Auto" Height="25" BorderThickness="1,2,0,2"/>
my other controls go here
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

Resources