I am working on a project where I have a GridView and I need to show an image and 3 TextBlocks. The image has a fixed Height and Width properties and the first TextBlock have either 1 line of text or 2. The other TextBlocks have only 1 line of text.
The problem is that if the first TextBlock has 1 line of text everything is shown perfectly but if the text is longer than one line the last TextBlock is not shown in the GridViewItem and it is pushed down where it gets hidden.
<GridView ItemsSource="{Binding HomeList, Mode=OneWay}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:ItemHelper">
<UserControl>
<StackPanel>
<Image Name="image" Source="{x:Bind ItemImage}"
Height="144" Width="256" HorizontalAlignment="Center"/>
<TextBlock Name="title" Text="{x:Bind ItemTitle}" Style="{StaticResource OneLinedItemTitle}"/>
<TextBlock Name="section" Text="{x:Bind ItemSection}"/>
<TextBlock Name="pubUpdate" Text="{x:Bind ItemPublishTime}"/>
</StackPanel>
</UserControl>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
I have also tried the above XAML with RelativePanel and the same thing happens. I want the height to be fixed at max height with 2 lines of text for title or adjustable for each item in the GridView.
As you can see that the first item shows 3 TextBlocks but the 2nd item shows only 2 where the first one has 2 lines of text.
I only see the following possible options:
Set the height of the StackPanel to be fixed for the max height of the items
Set the height of the title to be fixed with 2 lines of text
Maybe editing the default Style for GridViewItem would help
Or maybe there is any other possible option which doesn't involve setting the fixed height for any element.
Any suggestions? Thanks.
Why don't you use a Grid inside your UserControl instead of the StackPanel. The StackPanel sizes to content Heights only. I would use a Grid, set the RowDefinition at third Row to Height="*" and the other ones to Height="Auto". I tested this with an ItemsControl (that worked...)
<GridView ItemsSource="{Binding HomeList, Mode=OneWay}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:ItemHelper">
<UserControl>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Row="0" Name="image" Source="{x:Bind ItemImage}" Height="144" Width="256" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="1" Name="title" Text="{x:Bind ItemTitle}" Style="{StaticResource OneLinedItemTitle}"/>
<TextBlock Grid.Row="2" Name="section" Text="{x:Bind ItemSection}" TextWrapping="Wrap"/>
<TextBlock Grid.Row="3" Name="pubUpdate" Text="{x:Bind ItemPublishTime}"/>
</Grid>
</UserControl>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
It seems the first item is not rendering correctly (at least this is what happened to me). Check Justin XL answer, maybe it can help. Apparently the problem (from poor rendering) is solved by setting the ItemHeight property
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid ItemHeight="DesiredHeight"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
Related
I have created a UserControl that is suppose to display some text and then present a listbox for the user to select some item.
It is supposed to strech to the height to the grid cell it is placed in. And if there are more items than can fit on screen then to display a vertical scrollbar. After much trial and error I have finally managed to get it working as expected. But only when the row height is a pixel value. If I use any partial (by partial I mean the star symbol), the grid cell's height is not contained. Since I need the app the match screen size I need the partials to work.
Putting 100 items in the listbox suddenly makes the height of the entire grid is around 11000 (which I think is everything with no contraint). Meaning there is no scrollbar. See [Screenshot] https://i.stack.imgur.com/faES9.png.
I have a similar issue with my TextBox only horizontally. It will only activate when clicking on a specific pixel since it is empty the width is only 1 pixel. I hope someone can help me point out where I am going wrong, cause since I'm having more than one issue I suspect the problem is on my end.
This is my XAML code.
<UserControl x:Class="PackingStation.UserControls.SearchItemListing"
x:Name="SearchItemListingRoot"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PackingStation.UserControls"
mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="1000">
<Grid DataContext="{Binding ElementName=SearchItemListingRoot}"
x:Name="TheGrid"
VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=".1*" />
<RowDefinition Height=".1*" />
<!-- If this value isnt a pixel value it will not vertically strech to available space -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center"
Margin="0,0,0,0"
x:Name="TheHeadLineField"
Grid.Row="0"
Grid.Column="1">
<Label Style="{StaticResource LabelStyleHeadline32}"
Content="{Binding Title}"
HorizontalAlignment="Left"/>
<Label Style="{StaticResource LabelStyleText}"
HorizontalAlignment="Left"
Content="{Binding SubTitle}"
FontSize="20"/>
</StackPanel>
<!-- Search Field -->
<Border Style="{StaticResource Border6}"
x:Name="TheSearchField"
Grid.Row="1"
Grid.Column="1"
Background="{StaticResource ColorSummaryPanelBackground}"
BorderBrush="{StaticResource ColorSummaryPanelBorder}"
BorderThickness="1"
Margin="0,40,0,0">
<StackPanel Orientation="Horizontal"
Height="78"
HorizontalAlignment="Stretch">
<Image Stretch="Uniform"
Height="24"
Source="pack://application:,,,/WpfUI;component/Icons/Search.png"
Margin="36,0,0,0"
VerticalAlignment="Center"/>
<!-- Search Textbox -->
<!-- Similar issue with this textbox, only horizontally. With no content you have to hit a specific pixel to activate it -->
<TextBox Style="{StaticResource TextBoxSearchInlay}"
Name="TbxSearchTerm"
TextChanged="TextBoxBase_OnTextChanged"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
Margin="20,0,0,0"/>
</StackPanel>
</Border>
<!-- Search results listings -->
<ListBox ItemsSource="{Binding Items}"
x:Name="TheListBox"
Grid.Row="2"
Grid.Column="1"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch" Margin="0,-10,0,-10">
<Label Style="{StaticResource LabelSearchItem}"
Content="{Binding Name}"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
I could repro your problem when I put your UserControl in a StackPanel. When it's in a Grid the ListBox shows its vertical scrollbar. So, try your UserControl in a Grid.
I think this answer will give a good explanation about Grid and StackPanel stretching behavior.
I'm trying to create two scrollviewers that scroll vertically and horizontally respectively.
The scrolling should start when the manipulationdelta event is detected, and I have used the ChangeView method to move the scrollviewers accordingly. The vertical scrollviewer is ok, but it's not the same for the horizontal one.
I have added an image to show the 2 scrollviewers since i cannot post it right here.
Here's the code: XAML
<!--horizontal scrollviewer-->
<ScrollViewer x:Name="horizontalScrollViewer"
Grid.Column="1"
Grid.RowSpan="3"
HorizontalScrollMode="Disabled"
VerticalScrollMode="Disabled">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition Height="100"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<!--upperGrid-->
<GridView Grid.Row="0"
ScrollViewer.HorizontalScrollMode="Disabled"
ScrollViewer.VerticalScrollMode="Disabled"
ItemsSource="{Binding dataItems}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical"
MaximumRowsOrColumns="1"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Height="80" Width="80" Text="{Binding}"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<!--bottomGrid-->
<GridView Grid.Row="2"
ScrollViewer.HorizontalScrollMode="Disabled"
ScrollViewer.VerticalScrollMode="Disabled"
ItemsSource="{Binding dataItems}">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical"
MaximumRowsOrColumns="1"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Height="80" Width="80" Text="{Binding}"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
</ScrollViewer>
and the .cs
private void dataGrid_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var x = e.Delta.Translation.X;
var y = e.Delta.Translation.Y;
if(Math.Abs(x)> Math.Abs(y))
{
bool result = horizontalScrollViewer.ChangeView( horizontalScrollViewer.HorizontalOffset - x , null, null);
result = centralScrollViewer.ChangeView(horizontalScrollViewer.HorizontalOffset - x, null, null);
}
else
{
bool result = centralScrollViewer.ChangeView(null, verticalScrollViewer.VerticalOffset -y, null);
verticalScrollViewer.ChangeView(null, verticalScrollViewer.VerticalOffset - y, null);
}
}
In the msdn documentation I have read that :
horizontalOffset
Type: IReference [C++] | System.Nullable [.NET]
A value between 0 and ScrollableWidth that specifies the distance the content >should be scrolled horizontally.
but my ScrollableWidth is equal to zero and I can't understand why.
Does anyone know what's wrong with my code?
I've found a solution by myself!
I had to add the horizontalscrollbar visibility option on the horizontal scrollviewer. It's quite odd since I didn't need to add it to the vertical one. Anyway here's the code of the horizontal scrollviewer:
<ScrollViewer x:Name="horizontalScrollViewer"
Grid.RowSpan="3"
Grid.Column="1"
HorizontalScrollMode="Disabled"
HorizontalScrollBarVisibility="Auto"
VerticalScrollMode="Disabled">
I don't think you can scroll while scrolling is disabled. If you're just trying to hide the scrollbars, then do the following:
<ScrollViewer x:Name="horizontalScrollViewer"
Grid.Column="1"
Grid.RowSpan="3"
HorizontalScrollMode="Enabled"
VerticalScrollMode="Enabled"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
...
</ScrollViewer>
Iam working on a win 8.1app. I have a datatemplate
<DataTemplate x:Key="RadioOptionDataTemplate">
<Grid HorizontalAlignment="Left">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Margin="0 0 0 15">
<Run Text="{Binding name}"/><Run Text=":"/>
</TextBlock>
<ItemsControl Grid.Row="1" ItemsSource="{Binding GetOptions}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding}" Margin="0 0 10 10" IsChecked="True"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</DataTemplate>
It show data like this
Now if you see text cuts down from right end. If I set static content of radio button than everything looks well.
I want to know why this is happening in case of binding.
ItemsControl Item's Widths are calculating based on how much the size has it's first item needs. In your code 'No Rice' is your first item text & the second and third item texts are longer than the first item text. That is because the text wraps.
And if you set the first item text is longer , all other items will fit in the view & text will not cut off.
You can use text wrapping as one method for avoiding text cut off. Or you have to create a Items control with variable item widths.
Please check the following link for creating grid view with variable item width
How to Display Gridview items with variable width in Window 8?
Thanks
the problem with this code is that i have set the opacity of the grid to 0.5 and that make my grid box transparent(that is fine), but the problem is that the text and the image and the checkbox should be seen in full opacity. how can i make my grid transparent without affecting the inner elements?
tried:
i have make a stackpanel in the datatemplate and was trying to place it inside the grid with the margin property but the stackpanel cannot be made inside the listbox's datatemplate with grid. any solution to that
<ListBox Grid.Row="1" x:Name="BookCategories" ItemsSource="{Binding}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel ItemHeight="200" ItemWidth="200" Margin="10"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="#12161e" Opacity="0.5" Tap="Grid_Tap_1" Margin="10,-5,0,20" Height="200" Width="200">
<CheckBox Grid.Row="1" Margin="145,-15,-15,0" x:Name="Chkcategories" Click="Chkcategories_Click" >
<Image Margin="-80,-140,-15,0" Height="20" Width="20" Source="{Binding ElementName=Chkcategories, Path=IsChecked, Converter={StaticResource BoolToImageSource} }"></Image>
</CheckBox>
<Image Width="50" Opacity="100" Height="50" Margin="30,30,0,0" Source="Assets/icons/food.png"></Image>
<TextBlock Margin="40, 80, 0, 0" FontSize="22" Text="{Binding Path=CategoryName}"></TextBlock>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The Opacity setting is inherited for all child elements if set directly in the Grid Opacity=... setting. You should instead use opacity like this:
<Grid>
<Grid.Background>
<SolidColorBrush Color="#12161e" Opacity="0.5" />
</Grid.Background>
... content ...
</Grid>
You have to use alpha channel (0-255).
255 (max) * 0.5 (your opacity) = 127.5 => 128 => 80 hex
<Grid Background="#8012161e" ...
I'm currently trying to figure out how to show different types of objects in a GridView, look at this Pic for example:
the last element on the right side is different than the other elements, so if i bind an observablecollection to the GridView, how can i say that the last element is shown up in anohter layout.
currently I'm using this XAML-Code
<GridView x:Name="startView" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2" SelectionMode="None" Width="Auto">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock x:Name="DetailTitle" Height="74" Text="{Binding Title}" />
<Image x:Name="Image" Height="Auto" Width="Auto" Margin="0" Stretch="None" Source="{Binding LocalCoverUrl}" Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" MaximumRowsOrColumns="2" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
and this Code in the Back:
ObservableCollection<Movie> recentlyStarted = await Api.RecentlyStarted(3);
startView.DataContext = recentlyStarted;
but I have currently no clue how to let the last element show up in a different style
The easy way would be to have the two types of object as different classes (e.g. MoviePicStyle + MoviePlainStyle. Then move your DataTemplate out of the GridView, so that each object is picked up by type,
e.g.
<Window.Resources>
<DataTemplate DataType="{x:Type ViewModel:MoviePicStyle}">
<StackPanel>
<TextBlock x:Name="DetailTitle" Height="74" Text="{Binding Title}" />
<Image x:Name="Image" Height="Auto" Width="Auto" Margin="0" Stretch="None" Source="{Binding LocalCoverUrl}" Visibility="Collapsed" />
</StackPanel>
<DataTemplate DataType="{x:Type ViewModel:MoviePlainStyle}">
...Different View...
</DataTemplate>
</Window.Resources>
<GridView...
Use template selector property of gridview and depending upon the type of object select the template. I did the same in my project. you need to write your own DataTemplateSelector.
I referred below link
http://babaandthepigman.wordpress.com/2012/02/08/datatemplateselector-winrt/