I'm trying to make a Windows Phone page with 2 columns, where the columns fill all of their space to make rectangular buttons similar to the Windows Phone menu. Surprisingly, this is trickier than expected. I have the layout working, and the 2 columns, however, they are small rectangles, not filling their width or height.
I don't want to use any "Width = 250" or whatever. I'm purely interested in a responsive layout solution. My current code is below. I've been here for about 2 days now...
<ListView
Grid.Row="1"
ItemsSource="{Binding Locations}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Margin="12">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Button
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="12"
BorderThickness="0">
<Button.Template>
<ControlTemplate>
<StackPanel Background="{ThemeResource PhoneAccentBrush}">
<Image />
<TextBlock
TextAlignment="Center"
Text="{Binding Name}" />
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal"
MaximumRowsOrColumns="2"
HorizontalAlignment="Center"
VerticalChildrenAlignment="Stretch"
HorizontalChildrenAlignment="Stretch" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
Here's a screenshot of what it currently looks like. As you can see, the buttons have a massive margin that is not actually given by me...
http://gyazo.com/3c949bd9a6ac5d08b3e40bd5c9bb0e7b
As you say it looks like you do have two columns in your picture. I'm also seeing from your markup that you have 12 pixels margin on your list and 12 pixels margin on your buttons. That means that you're going to have at least 24 pixels of margin between all your UI elements. Looking at the picture I'm seeing closer to 60 pixels between UI elements. We should break this down further to see where the extra size is coming from.
For debugging purposes can you please add a temporary background color to your ListView and a different background color to your DataTemplate item's StackPanel. Then take a new screenshot and see what elements are consuming all the space. I bet it's the ListViewItem. You might want modify the ItemContainerStyle to remove any built in non-visible UI elements taking up space.
Related
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.
My listboxes are data driven from Lists of objects with databinding using a DataTemplate eg:
<ListBox x:Name="TheMainListBox"
ScrollViewer.IsVerticalRailEnabled="True"
ScrollViewer.IsHorizontalRailEnabled="False"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="540"
ItemsSource="{Binding}"
Width="Auto"
Margin="0"
Padding="0"
Background="Yellow"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SelectionChanged="TheMainListBox_SelectionChanged"
DoubleTapped="TheMainListBox_DoubleTapped"
>
The template:
<ListBox.ItemTemplate>
<DataTemplate>
<Grid or Stackpanel Background="Blue"
Padding="0"
BorderBrush="Black"
BorderThickness="1"
Margin="0"
>
.... Binding Textboxes/blocks
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
I end up with a yellow container, the ListBox, .. with blue rectangles inside, the ListBox items but there is a vertical gap between them. I can set a negative vertical-top margin but that is cruddy and doesn't work for the top item. How can I reduce the vertical gap between items to zero.
If a create a ListBox with static items, each in a ListBoxItem container, eg:
<ListBoxItem BorderThickness="1" Width="100" Height="50"
BorderBrush="Black" Background="Red"/>
It all works as required.
So how can I get rid of the vertical spacing between items with the ItemTemplate/DataBinding?
This is mission critical, thx in advance.
I don't have time to load up a proj to test but you should be able to just kill the margin/padding that could cause it. So add;
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
I haven't thought a lot of why this could be happening, haven't digged into styles ither, and my answer doesn't look nice, but try Margin="0,-2,0,-2"
<DataTemplate>
<Grid or Stackpanel Background="Blue"
Padding="0"
BorderBrush="Black"
BorderThickness="1"
Margin="0,-2,0,-2"
>
.... Binding Textboxes/blocks
</Grid>
</DataTemplate>
properly setting the height of the ListBoxItem will solve the issue. Here is the code snippet
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Height" Value="Your_Desired_Height"/>
</Style>
</ListBox.ItemContainerStyle>
For listbox please use Height property and for listview use MinHeight property. Replace the required height value in the Your_Desired_Height placeholder.
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
I am trying to get my ListView control to look real nice, but I can't get the ListViewItem to stretch to the full width of the ListView control.
I've seen it in many apps on the store. But I just can't get it:
I am beginning to think that maybe the apps that look like it is stretched are not actually using ListViews, but some other kind of List.
How do I make the Item stretch to the width of its container?
Below is what I am using:
<ListView x:Name="list" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0, 37, 0, 0" ItemsSource="{Binding Note}" Width="376" HorizontalContentAlignment="Stretch" Background="Magenta" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="376">
<TextBlock Text="{Binding Name, Mode=OneWay}" TextWrapping="Wrap" Padding="10, 0, 0, 0" HorizontalAlignment="Left" SelectionHighlightColor="#FF4617B4" />
<!--<TextBlock TextWrapping="Wrap" Text="Jan 20, 2013" FontSize="9" Foreground="#FF4E7189" HorizontalAlignment="Right" SelectionHighlightColor="#FF9BCAEC" />-->
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You've got a couple options. For whatever reason they have it set in the template so if you check out the default template you'll see the Margin="0,0,18,2" (also other odd margins on multiple objects stacking up for that matter) so if you really wanted to fix it, you could expose the default template and fix it directly, or make a copy of your own an apply directly, or for a quickie try just adding;
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="0" />
</Style>
</ListView.ItemContainerStyle>
Hope this helps.
I am looking to create a task profiler in WPF with an UI similar to the one of incredibuild.
Eg, timed tasks appear as strips on their respective line. Have a look at:
http://baoz.net/wp-content/2009/06/ib1.png
to see what I mean. I am unsure what the best way to tackle this problem is? Should I override the Panel class creating a custom layout panel for this or might there be an existing control/library out there that can fit my needs. I have so far had a look at various charting controls but am unsure of weither they can be tweaked to achieve this behaviour or not. I am really hoping for someone who has been using WPF for a while to help me narrow down my search. It is not exactly easy to know what to google for either :)
In WPF this kind of chart is absolutely trivial. No special charting package is required:
In your resources, define a DataTemplate for displaying the event whose width is bound to the event length:
<DataTemplate TargetType="{x:Type local:Event}">
<Border Width="{Binding EventLength}"> <!-- This sets the width -->
<Border Margin="1" Padding="1" StrokeThickness="1" Stroke="Black"
Background="{Binding EventColor}"> <!-- Actual border -->
<TextBlock Text="{Binding EventDescription}" />
</Border>
</Border>
</DataTemplate>
Also define a horizontal items panel template:
<ItemsPanelTemplate x:Key="HorizontalPanel"><DockPanel/></ItemsPanelTemplate>
Now your actual chart is trivial to build:
<ItemsControl ItemsSource="{Binding CPUs}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock Width="100" Text="{Binding Name}" /> <!-- CPU name -->
<Rectangle Width="1" Fill="Black" /> <!-- Vertical divider -->
<ItemsControl ItemsSource="{Binding Events}" <!-- Events -->
ItemsPanel="{StaticResource HorizontalPanel}" />
</DockPanel>
</DataTemplate>
</ItemsControl.Template>
</ItemsControl>
If you have gaps between your events, simply add a "Gap" object to your Events collection to represent them, then add a DataTemplate for gaps:
<DataTemplate TargetType="{x:Type local:Gap}">
<UIElement Width="{Binding GapWidth}" />
</DataTemplate>