UWP C# ListView not scrollable - c#

I have this ListView:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ScrollViewer VerticalScrollBarVisibility="Visible" VerticalScrollMode="Enabled">
<ListView x:Name="entryList" Width="360">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel BorderBrush="Gray">
<TextBlock Text="{Binding title}"></TextBlock>
<TextBlock Text="{Binding description}"></TextBlock>
<TextBlock Text="{Binding author}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
</Grid>
I get my data for ItemsSource calling a webservice in a seperate method (works all fine)
private async void Page_Loading(Windows.UI.Xaml.FrameworkElement sender, object args)
{
entryList.ItemsSource = await webserviceManager.getItems(param1, param2);
}
My ListView is filled with items as well, but I can't figure out why it isn't able to scroll vertically. Checking the ScrollableHeight I get allways 0 so I think the items are the problem, the control doesn't count them as logical items so far. If I give the ScrollViewer a concrete height all is fine - but thats no viable solution for I don't know on which device the app will run later. So I have no faintest idea what I could do else, maybe somebody can help me?
Edit: the DataSource got a
ObservableCollection<entryObject> objlist = new ObservableCollection<NewsObject>();
where entryObject is a simple data holding class with string properties .

I've solved the Problem - by changing all StackPanels to Grids with RowDefinitions.
<ListView x:Name="entryList" Width="360">
<ListView.ItemTemplate>
<DataTemplate>
<Grid BorderBrush="Gray">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="{Binding title}" Grid.Row="0"></TextBlock>
<TextBlock Text="{Binding description}" Grid.Row="1"></TextBlock>
<TextBlock Text="{Binding author}" Grid.Row="2"></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Also I changed my MainPage with the basic SplitView, where the frame in the content panel called the page with the ListView. Here has one of the Grid.Rows a constant height now - and, seems a little bit weird, but all is working fine now.
<SplitView.Content>
<Grid x:Name="mainPagePanel">
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition></RowDefinition>
<Button x:Name="HamburgerButton" FontFamily="Segoe MDL2 Assets" Content="" Width="50" Height="50" Background="Transparent" Click="HamburgerButton_Click" Grid.Row="0"/>
<Frame x:Name="viewFrame" Grid.Row="1"></Frame>
</Grid>
</SplitView.Content>

ListView already contains ScrollViewer in Style. So, just remove your inner ScrollViewer.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="entryList" Width="360">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel BorderBrush="Gray">
<TextBlock Text="{Binding title}"></TextBlock>
<TextBlock Text="{Binding description}"></TextBlock>
<TextBlock Text="{Binding author}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>

Related

How to add a separator to the Expander component in UWP app?

I'm looking for a way of implementing this kind of separator to the expander component in UWP app:
Any ideas how to do that?
I've managed to create the similar look of the expander, but I don't know how to implement separators?
Also, I would like to learn how to make expanders kind of "push" other components down when I expand them, so they don't overlap with other components, but simply move them.
Here's the XAML code for this expander:
<muxc:Expander x:Name="FontExpander"
x:Uid="FontExpander"
Width="1155"
IsExpanded="True"
Margin="22,323,0,0"
VerticalAlignment="Top"
Grid.Row="2"
Height="380"
HorizontalContentAlignment="Left"
ExpandDirection="Down">
<muxc:Expander.Header>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<FontIcon Margin="0,0,12,0"
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorPrimaryBrush}"
FontSize="16"
Glyph=""/>
<StackPanel Grid.Column="1"
Margin="0,12"
Orientation="Vertical">
<TextBlock x:Uid="SettingsFontTitle" Style="{StaticResource BodyTextBlockStyle}"/>
<TextBlock x:Uid="SettingsFontDescription"
Style="{StaticResource CaptionTextBlockStyle}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="WrapWholeWords"/>
</StackPanel>
</Grid>
</muxc:Expander.Header>
<muxc:Expander.Content>
<Grid Margin="-18,-170,-17,-170">
<TextBlock x:Name="SettingsFamily" x:Uid="SettingsFamily" Text="Family" Margin="50,51,1000,286"/>
<ComboBox x:Name="ComboBoxFamily" ItemsSource="{x:Bind Fonts}" Width="200" Margin="950,41,0,0" SelectionChanged="ComboBoxFamily_SelectionChanged" />
<TextBlock x:Name="SettingsStyle" x:Uid="SettingsStyle" Text="Style" Margin="50,106,995,218" Loaded="SettingsStyle_Loaded"/>
<ComboBox x:Name="ComboBoxStyle" Width="200" Margin="950,101,0,0">
<x:String>Regular</x:String>
</ComboBox>
<TextBlock x:Name="SettingsSize" x:Uid="SettingsSize" Text="Size" Margin="50,166,1002,158"/>
<ComboBox x:Name="ComboBoxSize" ItemsSource="{x:Bind FontSizes}" Width="200" Margin="950,161,0,0"/>
<TextBlock x:Name="Text" x:Uid="SettingsText" Text="Hello World! I am so excited to be here!" Margin="62,224,38,126" TextWrapping="Wrap" FontSize="{x:Bind (x:Double)ComboBoxSize.SelectedValue, Mode=OneWay}" TextAlignment="Center"/>
</Grid>
</muxc:Expander.Content>
</muxc:Expander>
Any help would be much appreciated!
A separate can for example be implemented using a Border or a Grid:
<Grid Background="DarkGray" Height="1" />
As a side note, you shouldn't use margins to position your elements. Use an appropriate layout Panel. Using a Grid, you should add ColumnDefinitions and RowDefinitions to it as examplified here.

TabItem DataTemplate with binding

I have a TabControl in my app. I'd like to have as many TabItems as many entries are in my dictionary.
Here's my dictionary:
public Dictionary<string , ObservableCollection<PerformanceCounter>> Counters
{
get { return _Counters; }
}
Dictionary<string, ObservableCollection<PerformanceCounter>> _Counters = new Dictionary<string , ObservableCollection<PerformanceCounter>>();
Every entry has a string key and ObservableCollection of PerformanceCounter objects. Important thing is the fact that every PerformanceCounter object has properties: CounterName and InstanceName - I'll need these two to display them.
Now, to my XAML:
<TabItem Header="Memory">
<Grid Name="RAMGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox Name="RAMListBox" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" ItemsSource="{Binding Memory, Mode=OneWay}" SelectionMode="Multiple" BorderThickness="1" BorderBrush="#FF8B8B8B" SelectionChanged="RAMListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding CounterName, Mode=OneWay}" />
<Run Text="{Binding InstanceName, Mode=OneWay}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Name="RAMSelectAllButton" Margin="0,10,0,0" Grid.Column="0" Grid.Row="1" Click="RAMSelectAllButton_Click" >
<TextBlock Text="SELECT ALL"/>
</Button>
<Button Name="RAMUnSelectAllButton" Margin="0,10,0,0" Grid.Column="1" Grid.Row="1" Click="RAMUnSelectAllButton_Click" >
<TextBlock Text="UNSELECT ALL"/>
</Button>
</Grid>
</TabItem>
That's what I did and, as you might already know, it does not work. The above code is only for one entry of my dictionary, where the key is "Memory".
In my code I set DataContext:
this.DataContext = appData.Counters;
appData.Counters is that dictionary I presented at the beginning.
Here's what I'd like to achieve:
No matter how many entries there are in my dictionary, my TabControl would display TabItem for each of them.
Each TabItem has a ListBox and 2 buttons. I'll need too be able to access those (in order to clear the list and to have click event for each button).
I really don't know how to do it, I hope you can help me out.
Binding TabControl to items in Dictionary:
<Window.Resources>
<DataTemplate x:Key="templateForTheContent" >
<StackPanel>
<ListBox Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0"
ItemsSource="{Binding Value, Mode=OneWay}"
SelectionMode="Multiple"
BorderThickness="1" BorderBrush="#FF8B8B8B">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding CounterName, Mode=OneWay}" />
<Run Text="{Binding InstanceName, Mode=OneWay}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="templateForTheHeader" >
<TextBlock Text="{Binding Key}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<TabControl TabStripPlacement="Left" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Counters}"
ContentTemplate="{StaticResource templateForTheContent}"
ItemTemplate="{StaticResource templateForTheHeader}">
</TabControl>
</Grid>
Now, Dictionary is not observable so if items will be added/removed during runtime, you may consider using something like ObservableDictionary instead
Create a ViewModel-class containing:
your Dictionary
two ICommand-Implementations for your Buttons
then
set the ViewModel-class as DataContext of the TabControl
set Counters as the ItemSource of the TabControl
reuse your XAML-Code defined within the TabItem and use it as
the Tabcontrol.ContentTemplate
Bind .Command of your Buttons to the ICommands in your ViewModel using RelativeSource
see for samples:
ContentTemplate: https://wpf.2000things.com/tag/tabcontrol/
ICommand https://stackoverflow.com/a/1468830/4919708
RelativeSource: https://stackoverflow.com/a/84317/4919708
As i said in one of the comments above I changed my Dictionary to this:
//list of all counters
public ObservableCollection<ObservableCollection<PerformanceCounter>> Counters
{
get { return _Counters; }
}
ObservableCollection<ObservableCollection<PerformanceCounter>> _Counters = new ObservableCollection<ObservableCollection<PerformanceCounter>>();
i used #Arie's solution to write this XAML:
<DataTemplate x:Key="templateForTheContent" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0"
ItemsSource="{Binding}"
SelectionMode="Multiple"
BorderThickness="1" BorderBrush="#FF8B8B8B">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding CounterName, Mode=OneWay}" />
<Run Text="{Binding InstanceName, Mode=OneWay}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Name="RAMSelectAllButton" Margin="0,10,0,0" Grid.Column="0" Grid.Row="1" >
<TextBlock Text="SELECT ALL"/>
</Button>
<Button Name="RAMUnSelectAllButton" Margin="0,10,0,0" Grid.Column="1" Grid.Row="1" >
<TextBlock Text="UNSELECT ALL"/>
</Button>
</Grid>
</DataTemplate>
<DataTemplate x:Key="templateForTheHeader" >
<TextBlock Text="{Binding CategoryName}"/>
</DataTemplate>
</Window.Resources>
It displays correctly as many Tabs as I add entries to my Class ObservableCollection in the code behind.
Now i have a new problem: I don't know how to access each listBox from each Tab. i need to be able to read the list of selected objects.

"Frozen" column when scrolling horizontal

I am new to c# and UWP and looking for a way to enable horizontal scrolling with frozen column.
Currently this is my list :
<ScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ListView x:Name="Listeoffice" ItemsSource ="{x:Bind salesoffices}" Margin="0,60,0,0" ScrollViewer.VerticalScrollMode="Disabled" ScrollViewer.HorizontalScrollMode="Enabled">
<ListView.ItemTemplate>
<DataTemplate x:Name="Template1" x:DataType ="data:office">
<StackPanel Orientation="Horizontal" Margin="0,20,0,0" Width="700" >
<TextBlock Text="{x:Bind caption}" Margin="10,0,0,0" Width="50"/>
<TextBlock Text="{x:Bind invoices}" Margin="50,0,0,0" Width="90"/>
<TextBlock Text="{x:Bind order_entry}" Margin="30,0,10,0" Width="88"/>
<TextBlock Text="{x:Bind delivery_backlog}" Margin="10,0,20,0" Width="100"/>
<TextBlock Text="{x:Bind delivery_new}" Margin="10,0" Width="88"/>
<TextBlock Text="{x:Bind delivery_total}" Margin="20,0,10,0" Width="88"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
The problem is with this approach when I scroll horizontal the first column will not stay.
I read something about using a second ScrollViewer just for the first column but i cant get it working.
EDIT :
Sry wasn´t precise enough. I dont want a header but the first column (the left one) to stay even if the list gets scrolled horizontal.
I think you want header of your ListView.
ListView has a Header property.
<ListView>
<ListView.Header>
your header
</ListView.Header>
</ListView>

Stackpanel: Black background on wp8

I have one problem - my stackpanel is vey big and it breaks(background color is changed to black).. What should i do to improve it?
<Grid x:Name="LayoutRoot" Background="#FF2D2D2D" >
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Orientation="Horizontal" Grid.Row="0">
..
</StackPanel>
<ScrollViewer Name="viewer" Grid.Row="1" >
<StackPanel Name="ContentGrid" Canvas.ZIndex="1" Margin="0, 0,0,80" Background="White" Width="452">
<Image Name="ImageImage" Height="300" VerticalAlignment="Top"/>
<TextBlock Name="DateText" TextWrapping="Wrap" TextAlignment="Center" FontSize="18" Foreground="Black"/>
<TextBlock Name="TitleText" TextWrapping="Wrap" FontSize="20" TextAlignment="Center" Foreground="Black" Margin="10,0"/>
<TextBlock TextWrapping="Wrap" Margin="10,15,10,2" Name="DescroptionText" FontSize="23" Foreground="#FF494949" FontFamily="Portable User Interface"/>
<TextBlock TextWrapping="Wrap" TextTrimming="WordEllipsis" Margin="10,0,10,2" Name="DescroptionText2" FontSize="23" Foreground="#FF494949"/>
<ListBox SelectionChanged="GridImages_SelectionChanged" ScrollViewer.VerticalScrollBarVisibility="Disabled" Name="GridImages" ItemTemplate="{StaticResource AttachmentsItemTemlate}" Grid.RowSpan="2" FontFamily="Portable User Interface" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" FlowDirection="LeftToRight" ItemWidth="150" ItemHeight="150"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</StackPanel>
</ScrollViewer>
</Grid>
There is a limitation of 2048px in Windows Phone UIElements.
You should try to break your different elements into smaller elements (for example: you could put several stackpanels inside the first one).
In TextBox elements there is a workaround explained here.
Best this is to make the Main Window to white background and Make your stackpanel as transparent background instead of giving any color to it. It works great as I have tested it.
Try this code, but first you need to add windows toolkit library.
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
<toolkit:PhoneTextBox
TextWrapping="Wrap"
Name="txtString"
ScrollViewer.VerticalScrollBarVisibility="Visible"
MaxHeight="200"
PlaceholderText="Add text"
Padding="5"
Width="370"
FontFamily="Open Sans Light"
FontSize="22"
Height="Auto" ///Use Auto or provide height value
Margin="10"
/>
This code is used for Scrolling as well work for Auto Growing Textbox. If you don't want Auto Growing Textbox then provide height instead of Auto in Height attribute.

Windows Phone 8 - TextBlock in StackPanel not wrapping Text properly?

I have an app that is based on the Panorama control. Clicking on an item on one of the Panorama control's pages (tabs) goes to a details page. On that details page I have the XAML below that renders the item content. As you can see there is a TextBlock hosted by a StackPanel in the phone:PanoramaItem.Header element. I want the text in that element to wrap the video title the TextBlock is bound to in the view model. I have TextWrapping set to wrap and I have assigned it a fixed width so the TextBlock doesn't grow/expand (and therefore won't wrap). The text does wrap, but some lines still appear clipped with some words appearing "cut off". What is wrong with my XAML?
I read about using a DockPanel instead:
TextBlock Wrapping in WPF Layout
But this app has a StackPanel used on a lot of different pages so if I can stick with a StackPanel I'd prefer it.
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Visibility="{Binding IsInternetAvailable}" Background="{StaticResource PhoneAccentBrush}" Height="30">
<TextBlock Text="{Binding Path=LocalizedResources.NoConnection, Source={StaticResource LocalizedStrings}}" Margin="10, 0"/>
</Grid>
<phone:Panorama x:Name="PanoramaFavorites_DetailVideos" Grid.Row="2" Foreground="{StaticResource CustomApplicationTextBrush}" Background="{StaticResource CustomApplicationBackgroundImage}" SelectionChanged="panoramaFavorites_DetailVideos_SelectionChanged">
<phone:Panorama.Title>
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
<Image Height="85" Width="85" Source="http://appstudiodata.blob.core.windows.net/apps/1383/db936107-bce6-41a2-9d95-1d342f66c6bb/res/Logo-b3883645-a6cd-4cc8-82be-97c87a266656.png" Stretch="Uniform" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="5,0,10,5" RenderTransformOrigin="0.5,0.5" />
<TextBlock FontSize="92" Text="Robot Videos" FontFamily="Segoe WP Light" Foreground="{StaticResource CustomTitleApplicationTextBrush}" VerticalAlignment="Stretch"/>
</StackPanel>
</phone:Panorama.Title>
<phone:PanoramaItem x:Name="PanoramaFavorites_DetailVideos0" Margin="0,0,0,25">
<phone:PanoramaItem.Header>
<StackPanel Orientation="Horizontal" Margin="0,7,0,0">
<TextBlock Text="{Binding CurrentYouTubeVideo.Title, Converter={StaticResource SanitizeString}}" Foreground="{StaticResource CustomApplicationTextBrush}" FontSize="36" TextWrapping="Wrap" Width="440" Height="170"/>
</StackPanel>
</phone:PanoramaItem.Header>
<ctl:FlipControl NextElementCommand="{Binding NextpanoramaFavorites_DetailVideos0}" PreviousElementCommand="{Binding PreviouspanoramaFavorites_DetailVideos0}" ShowPreviousButton="{Binding HasPreviouspanoramaFavorites_DetailVideos0}" ShowNextButton="{Binding HasNextpanoramaFavorites_DetailVideos0}">
<ctl:FlipControl.InnerContent>
<Grid Margin="10,5,5,5">
<ScrollViewer>
<ctl:YouTubePlayer Margin="0,10" MaxHeight="250" VerticalAlignment="Top" VideoId="{Binding CurrentYouTubeVideo.VideoId, TargetNullValue={StaticResource DefaultNoImageValue}}"/>
</ScrollViewer>
</Grid>
</ctl:FlipControl.InnerContent>
</ctl:FlipControl>
</phone:PanoramaItem>
</phone:Panorama>
</Grid>
As per your comments, this works for me:
<StackPanel Orientation="Vertical" Margin="0,7,0,0">
<TextBlock Text="{Binding CurrentYouTubeVideo.Title, Converter={StaticResource SanitizeString}}"
Foreground="{StaticResource CustomApplicationTextBrush}"
FontSize="36"
TextWrapping="Wrap"
MaxWidth="440"/>
</StackPanel>

Categories