Align GridView children to top of cell in UWP XAML - c#

I am using GridView to display a grid of variable-height items, except each cell is aligned to the middle of the row.
My markup is
<GridView ItemsSource="{x:Bind Bounties}" SelectionMode="None" HorizontalAlignment="Left"
VerticalAlignment="Top" >
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:Bounty">
<Grid>
<TextBlock Margin="12" MaxWidth="350" HorizontalAlignment="Left"
Text="{x:Bind ItemDefinition.DisplayProperties.Description}"
Style="{ThemeResource BodyTextBlockStyle}" TextWrapping="WrapWholeWords" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
How can I get each cell to align to the top left of its row?

The internal content of the GridViewItem is vertically centered, this is the default style, if you want to modify it, please try this:
<GridView ...>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
...
</GridView.ItemTemplate>
</GridView>
In addition, if you want to make the elements in the GridView adaptive height (the default is the height of the first element or the preset height as the height of all items), you can try StaggeredPanel in Windows Community Toolkit.
Thanks.

Related

How do I get rid of unwanted padding in a Listview row

I am trying to figure out how to get rid of the padding below the text in a listview row:
And my markup for the Listview:
<ListView
ItemsSource ="{Binding AllowedApplicants}"
Height="250"
Width="219"
VerticalAlignment="Top"
Grid.Row="3"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="20,5"
BorderBrush="Bisque"
BorderThickness="2">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Padding="5,5" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I can't figure out where this extra padding (red arrow) is coming from. The properties for the row's padding and margins defaults to zero all around. I added the five to keep the text off the borders. The list view row seems to have a default Height which cannot be adjusted.
Try adding
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="MinHeight" Value="0"/>
</Style>
</ListView.ItemContainerStyle>
to your List View or use Live Property Explorer and Live Visual Tree Viewer from Visual Studio and peek into the ListViewItem.

How can i make a ListView's items take up all the available height?

I am trying to make a column chart using WPF. For the Y axis I have a list of values which I would like to display on the control.
I have a ListView bound to the collection. How can I get the items to spread over the entire length of the list view rather then squish together at the top? And is the ListViewthe correct control to use for this?
Here is a sample of my Xaml:
<ListView Grid.Row="1" Grid.Column="1" Grid.RowSpan="2"
ItemsSource="{Binding YAxisValues}"
Background="Gray" VerticalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Path=Value}"
Foreground="White"
HorizontalAlignment="Left"
FontSize="12" Width="50"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
On the left is the list view as i currently have it.
On the right is my desired result.
How can I change my ListView to get there? Or do I need to use a different control entirely?
with UniformGrid used as ItemsPanel items get equal height
<ListView Name="Axis" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2"
ItemsSource="{Binding YAxisValues}"
Background="Gray" VerticalContentAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<!--no changes-->
</ListView.ItemTemplate>
</ListView>
there can be a issue when ListView doesn't have enough height for all elements. In that case I would put ListView into ViewBox
Set HorizontalContentAlignment to Stretch for items.
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>

How to get rid of box selection border of GridView UWP

I have this gridview which works fine, but everytime I select an item I got this blue line around the item, how to remove it ?
<GridView Margin="5,15,0,0" x:Name="List" ItemsSource="{Binding}" SelectionChanged="List_SelectionChanged">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Margin="11">
<StackPanel BorderBrush="Black" Orientation="Vertical">
<Image Width="150" Height="150" Source="{Binding Way}" />
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid MaximumRowsOrColumns="2" Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
The following fixed it for me:
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewItem">
<ListViewItemPresenter
SelectedBackground="Transparent"
SelectedPointerOverBackground="Transparent"
PressedBackground="Transparent"
SelectedPressedBackground="Transparent"
/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GridView.ItemContainerStyle>
To remove the selection blue border of GridView, we can modify the template of GridView. To modify the template of GridViewItem, we can select the GridView in "Document Outline" and right click, then select "Edit Additional Templates"→ "Edit Generated Item Container (ItemContainerStyle)" → "Edit a Copy...".
In the Style, there is a ListViewItemPresenter in it.
When developing for Windows 10, use ListViewItemPresenter instead of GridViewItemPresenter in your item container style, both for ListView and for GridView.
For more info, see ListViewItemPresenter.
The color of blue line around the item is defined by SelectedBackground="{ThemeResource SystemControlHighlightAccentBrush}". We can set the SelectedBackground="Transparent", then there is no blue line around the item.
This is how I do it. Although it's not difficult to change the style, this requires about 99% less xaml (and a bit more code) to accomplish. You will have to remove the SelectionChanged event, specify the data type for your DataTemplate and add a Tapped event to each item.
<GridView SelectionMode="None" ItemsSource="{Binding}"
<GridView.ItemTemplate>
<DataTemplate x:DataType="YourType">
<Grid Tapped="Grid_Tapped_For_Every_Item">
...
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
...
</GridView>
in code file:
private void Grid_Tapped_For_Every_Item(object sender, TappedRoutedEventArgs e){
var g = (Grid) sender;
var myClass = (YourType)g.DataContext;
//Do whatever you were going to do in the SelectionChanged event
}

ListView in Windows Phone 8.1 Wobbles while scrolling though long list (XAML)

I'm having issues with scrolling through ListViews in my Windows Phone 8.1 App. Short lists scroll just fine, scrolling smoothly however as soon Virtualization kicks in the entire ListView "wobbles" to the left slightly, but noticeable enough to be annoying.
I've tried remove all the transitions to no effect as well as having items load incrementally to no success. Setting the item panel to a StackPanel (removing virtualization) fixes the issue but is not preferable.
My listviews are binding to a property in the DefaultViewModel that comes with the Basic Page Template.
What am I doing wrong and what are causing my ListViews to exhibit this behavior?
XAML:
<ListView x:Name="searchResultsList" IsItemClickEnabled="True" ItemClick="ListView_ItemClick" ItemsSource="{Binding searchResults}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0,0,0,20" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Width="80" Height="80">
<Image Source="{Binding Image}" />
</Border>
<StackPanel Grid.Column="2">
<TextBlock Text="{Binding PodcastTitle}" TextWrapping="WrapWholeWords" FontSize="{StaticResource TextStyleExtraLargeFontSize}" />
<TextBlock Text="{Binding LastUpdated, Converter={StaticResource dateConverter}}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" />
<TextBlock Text="{Binding PodcastArtist}" TextWrapping="WrapWholeWords" Style="{ThemeResource ListViewItemContentTextBlockStyle}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So this seems to be an OS issue, as evidenced in this thread on the MS forums: http://social.msdn.microsoft.com/Forums/en-US/9a363d33-5760-4d38-9c81-84259c4edcbe/listview-jiggles-horizontally-when-large-item-about-to-scroll-in-or-out-in-windows-phone-81-preview?forum=WindowsPhonePreviewSDK&prof=required.
The issue does indeed lie in virtualization, with items that have no fixed width. Using star as the width or making the horizontal alignment stretch won't work so the only solution that takes account orientation and resolution was to bind the width to the ListView's container's ActualWidth property:
<Grid x:name="contentRoot" Margin="19,9.5,19,0">
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width={Binding ActualWidth, ElementName=contentRoot} />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
The first element in the listview is not displayed because the ActiualWidth of the Grid is 0 in the first second, when loaded the page. This is the solution, that's working for me:
<Grid x:Name="contentRoot" Margin="20">
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<Grid MinWidth="{Binding ActualWidth, ElementName=contentRoot}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
This is a really annoying bug. I can't understand why this is not fixed since years now.
Imho stretching items in a vertical scrolling listview is a very basic feature and should work 100%.
A possible workaround is also this snipped, which should also be aware of size changes :
public class StrechItemsListView : ListView
{
public StrechItemsListView()
{
SizeChanged += StrechItemsListView_SizeChanged;
}
private void StrechItemsListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ItemsPanelRoot != null)
{
ItemsPanelRoot.Width = e.NewSize.Width;
}
}
}
Changing the xaml only to a custom listview type is less work and cleaner then edit every datatemplate etc. Just my 2 cents.
My Practice seems to work. At least in WP8.1.
Just set the ItemsPanelTemplate in the <ListView></ListView> Block explicitly, but not use
Style="{StaticResource ListViewStyle1}" or something else.
Sample Code:
<ListView ItemsSource="{Binding RadioList}" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollMode="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollMode="Auto">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="10,3,10,0">
<TextBlock Text="{Binding RadioName}" FontSize="15" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" Width="{Binding PhoneWidth}"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
The HorizontalContentAlignment and Width of VirtualizingStackPanel settings are used to center the content in the ListView .You can move these settings freely.I don't know why, but it does work.
This was fixed on Windows 10 for Windows 8.1 apps

Textwrapping within Textblock within Togglebutton within ListBox ItemTemplate

I'm trying to achieve a ToggleButton control template for listbox items. This is to be used in an application where the user can click on the listbox items to show a certain piece of functionality.
The listbox item template is defined as follows:
<Style x:Key="ExampleListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ToggleButton IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"
HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch">
<StackPanel Orientation="Vertical">
<TextBlock x:Name="ExampleTitle" Grid.Row="0" Foreground="#333333"
FontFamily="pack://application:,,,/Resources/Fonts/#Neuropol Regular"
FontSize="16" Height="26" TextAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" Text="{Binding ExampleDisplayName}"
Margin="5"></TextBlock>
<TextBlock Grid.Row="1" Foreground="#333333" Margin="5,-5,5,3" HorizontalAlignment="Stretch"
TextAlignment="Left" FontFamily="Verdana" VerticalAlignment="Top"
TextWrapping="Wrap" Text="{Binding ExampleDescription}"/>
</StackPanel>
</ToggleButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and the listbox is defined as
<ListBox x:Name="_examplesListBox"
SelectionMode="Single"
BorderBrush="Transparent"
Background="Transparent"
ItemsSource="{Binding AllExamples}"
ItemContainerStyle="{StaticResource ExampleListBoxItemStyle}"
SelectedItem="{Binding SelectedExample, Mode=TwoWay}"/>
Here I have two textblocks, one bound to ExampleDisplayName, the other bound to ExampleDescription. The effect I am trying to achieve is to get the second textblock (description) to wrap around, constrained by the available space.
This is what I'm getting now:
What I'd like is for the second line showing example description to wrap based on the size of the listbox. When the application starts the listbox should auto-size to the first line + margin.
Any suggestions?
Removing that horizontal scrollbar should help with text wrapping:
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">
I'm not quite sure how to auto-size ListBox on startup based on first text line size using only XAML.

Categories

Resources