Xamarin Forms - Append labels to BoxView using C# - c#

I would like to append labels to a box view using C#. The labels have to correspond to certain columns within each row.
The labels should fill the columns under the headers as in the picture below:
However after appending the the content to the Grid element it becomes a jumbled mess. Below is my code
.xaml
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="{StaticResource dividerThickness}" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource dividerThickness}" />
<ColumnDefinition Width="45" />
<ColumnDefinition Width="{StaticResource dividerThickness}" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="{StaticResource dividerThickness}" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="{StaticResource dividerThickness}" />
<ColumnDefinition Width="45" />
<ColumnDefinition Width="{StaticResource dividerThickness}" />
<ColumnDefinition Width="45" />
<ColumnDefinition Width="{StaticResource dividerThickness}" />
<ColumnDefinition Width="45" />
<ColumnDefinition Width="{StaticResource dividerThickness}" />
<ColumnDefinition Width="45" />
<ColumnDefinition Width="{StaticResource dividerThickness}" />
</Grid.ColumnDefinitions>
<!-- Vertical Lines -->
<BoxView Grid.Row="0" Grid.Column="0" Grid.RowSpan="7" />
<BoxView Grid.Row="0" Grid.Column="2" Grid.RowSpan="7" />
<BoxView Grid.Row="0" Grid.Column="4" Grid.RowSpan="7" />
<BoxView Grid.Row="0" Grid.Column="6" Grid.RowSpan="7" />
<BoxView Grid.Row="0" Grid.Column="8" Grid.RowSpan="7" />
<BoxView Grid.Row="0" Grid.Column="10" Grid.RowSpan="7" />
<BoxView Grid.Row="0" Grid.Column="12" Grid.RowSpan="7" />
<BoxView Grid.Row="0" Grid.Column="14" Grid.RowSpan="7" />
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="14" Text="Title" Style="{StaticResource headerRowStyle}" />
<BoxView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="14" />
<Label Grid.Row="2" Grid.Column="1" Text="Head 1" Style="{StaticResource resultTypeRow}" />
<Label Grid.Row="2" Grid.Column="3" Text="Head 2" Style="{StaticResource resultTypeRow}" />
<Label Grid.Row="2" Grid.Column="5" Text="Head 3" Style="{StaticResource resultTypeRow}" />
<Label Grid.Row="2" Grid.Column="7" Text="Head 4" Style="{StaticResource resultTypeRow}" />
<Label Grid.Row="2" Grid.Column="9" Text="Head 5" Style="{StaticResource resultTypeRow}" />
<Label Grid.Row="2" Grid.Column="11" Text="Head 6" Style="{StaticResource resultTypeRow}" />
<Label Grid.Row="2" Grid.Column="13" Text="Head 7" Style="{StaticResource resultTypeRow}" />
</Grid>
data.xaml.cs
protected override void OnAppearing()
{
base.OnAppearing();
var row = 3;
foreach (var result in Results)
{
var dist = new Label
{
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
FontSize = 9,
Text = result.Dist.ToString(),
};
var cycle = new Label
{
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
FontSize = 9,
Text = result.cycle.ToString(),
};
//REST OF LABELS HERE THEN APPEND TO PANEL
//Panel is the x:Name of the Grid Element
Panel.Children.Add(dist,1,row);
Panel.Children.Add(cycle, 3, row);
Panel.Children.Add(data, 5, row);
Panel.Children.Add(data2, 7, row);
Panel.Children.Add(data3, 9, row);
Panel.Children.Add(data4, 11, row);
Panel.Children.Add(data5, 13, row);
row++;
count++;
}
}
Any idea what I need to do be able to neatly fit my results into those columns?

Related

Xamarin forms -> PopUpView showing whitespace, but how to remove it?

Hope everyone is well. I'm running into a UI problem with my cross platform app for xamarin.forms. Basically it shows different on ios when compared to android.
I have a function on the AdminPage that when button clicks opens the PopupView, the popUp will either contain details on the user, or the order, for this example we are using orderDetails
private void ShowUserDetails_Clicked(object Sender, EventArgs e)
{
Button button = (Button)Sender;
string UserId = button.CommandParameter.ToString();
PopupNavigation.Instance.PushAsync(new PopupView(-1, int.Parse(UserId)));
}
The problem lies in the UI of the popUp, if you notice the android phone on the left of the image below. It loads the way I want it to. Displaying lable for email | phone number, followed by listview of OrderDetails below. As you can see it looks fine on the android. The problem is on the ios. Where is the whitespace coming from at the top of the PopUpView?
If you take a close look at the PopUpView on the iphone 11, there is a scroll bar to the right of the popUp . It starts where the text starts, and I cant scroll any further up. Its almost as if there is an extra row placed before anything else. I have looked extensively through the code and can't figure it out. So I want to remove the whitespace, have even tried listview.scrollTo for the listview but with no success..any help would be great thank you
<?xml version="1.0" encoding="utf-8" ?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BottleShop.Views.PopupView"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:converters="clr-namespace:BottleShop.ViewModels.Converters">
<StackLayout x:Name="StackSearchResultsOuter" BackgroundColor="Transparent" HorizontalOptions="Center" VerticalOptions="Center">
<StackLayout.Resources>
<converters:ProductIdToProductNameConverter x:Key="converter"/>
</StackLayout.Resources>
<BoxView x:Name="InvisibleSpacer" BackgroundColor = "Transparent"
HeightRequest="80" />
<StackLayout x:Name="StackLayoutOrders" IsVisible="{Binding SLOrders}">
<ListView BackgroundColor="White" ItemsSource="{Binding PreviousOrderDetailsForUserLV}" HasUnevenRows="True" SeparatorVisibility="None">
<ListView.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="20*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="0" x:Name="UserInfoLabel" HorizontalOptions="Center" Margin="10,10,0,0"/>
<BoxView Grid.Row="1"
Grid.ColumnSpan="4"
BackgroundColor="LightGray"/>
<Label Grid.Column="0" Text="Product" Grid.Row="1" HorizontalOptions="Center" Margin="0,10,0,0"/>
<Label Grid.Column="1" Grid.Row="1" Text="Quantity" HorizontalOptions="Center" Margin="0,10,0,0"/>
<Label Grid.Column="2" Grid.Row="1" Text="Price" HorizontalOptions="Center" Margin="0,10,0,0"/>
<Label Grid.Column="3" Grid.Row="1" Text="Sub" HorizontalOptions="Center" Margin="0,10,0,0"/>
<!--<BoxView Grid.Row="1"
Grid.ColumnSpan="4"
HeightRequest="1"
BackgroundColor="LightGray"/> -->
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10" RowSpacing="10" ColumnSpacing="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="43*" />
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="24*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" HorizontalOptions="StartAndExpand" VerticalOptions="StartAndExpand" Text="{Binding ProductId, Converter={StaticResource converter}}"/>
<Label Grid.Column="1" Grid.Row="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Text="{Binding Quantity}"/>
<Label Grid.Column="2" Grid.Row="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Text="{Binding PriceOfItem, StringFormat='£{0:0.00}'}"/>
<Label Grid.Column="3" Grid.Row="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" Text="{Binding SubtotalForThisItem, StringFormat='£{0:0.00}'}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
<StackLayout x:Name="StackLayoutUsers" IsVisible="{Binding SLUsers}">
<ListView x:Name="UsersListView" BackgroundColor="White" ItemsSource="{Binding AllExistingUsersLV}" HasUnevenRows="True" SeparatorVisibility="None">
<ListView.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="20*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="Address Line 1" Grid.Row="0" HorizontalOptions="Center" Margin="0,10,0,0"/>
<Label Grid.Column="1" Grid.Row="0" Text="Line 2" HorizontalOptions="Center" Margin="0,10,0,0"/>
<Label Grid.Column="2" Grid.Row="0" Text="Town" HorizontalOptions="Center" Margin="0,10,0,0"/>
<Label Grid.Column="3" Grid.Row="0" Text="Mobile" HorizontalOptions="Center" Margin="0,10,0,0"/>
<BoxView Grid.Row="1"
Grid.ColumnSpan="4"
HeightRequest="1"
BackgroundColor="LightGray"/>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10" RowSpacing="10" ColumnSpacing="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="43*" />
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="24*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" HorizontalOptions="StartAndExpand" VerticalOptions="EndAndExpand" Text="{Binding AddressLine1}"/>
<Label Grid.Column="1" Grid.Row="0" HorizontalOptions="StartAndExpand" VerticalOptions="EndAndExpand" Text="{Binding AddressLine2}"/>
<Label Grid.Column="2" Grid.Row="0" HorizontalOptions="EndAndExpand" VerticalOptions="EndAndExpand" Text="{Binding City}"/>
<Label Grid.Column="3" Grid.Row="0" HorizontalOptions="EndAndExpand" VerticalOptions="EndAndExpand" Text="{Binding MobileNumber}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</StackLayout>
<!-- </Grid> -->
</pages:PopupPage>
using BottleShop.Data;
using BottleShop.Models;
using Microsoft.AppCenter.Crashes;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Xamarin.Forms.Xaml;
namespace BottleShop.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PopupView //: ContentView
{
public ObservableCollection<OrderDetailsModel> PreviousOrderDetailsForUserLV { get; set; }
OrdersDatabaseController RecentOrdersController = new OrdersDatabaseController();
public ObservableCollection<UserModel> AllExistingUsersLV { get; set; }
UserDatabaseController UserController = new UserDatabaseController();
public bool SLOrders { get; set; }
public bool SLUsers { get; set; }
public PopupView(int OrderId, int UserId)
{
try
{
InitializeComponent();
//Show Orders PopUp
if (OrderId != -1)
{
SLOrders = true;
SLUsers = false;
List<OrderDetailsModel> RecentOrderDetailsList = RecentOrdersController.GetAllOrderDetailsByOrderId(OrderId);
PreviousOrderDetailsForUserLV = new ObservableCollection<OrderDetailsModel>(RecentOrderDetailsList as List<OrderDetailsModel>);
int startingHeightOfSL = 180;
int countOfOrderDetailRecords = PreviousOrderDetailsForUserLV.Count;
var tempHeightofStackSearchResults = countOfOrderDetailRecords * 40;
if (countOfOrderDetailRecords > 1)
{
StackSearchResultsOuter.HeightRequest = startingHeightOfSL + tempHeightofStackSearchResults;
}
else
{
StackSearchResultsOuter.HeightRequest = startingHeightOfSL;
}
UserInfoLabel.Text = "Email: " + PreviousOrderDetailsForUserLV[0].UserName + " | " + "Mobile: " + PreviousOrderDetailsForUserLV[0].UserMobileNumber;
}
else //Show Users PopUp
{
if(UserId != -1)
{
var a = 1;
SLOrders = false;
SLUsers = true;
List<UserModel> UsersList = UserController.GetUserWithId(UserId);
if (UsersList != null)
{
AllExistingUsersLV = new ObservableCollection<UserModel>(UsersList as List<UserModel>);
}
StackSearchResultsOuter.HeightRequest = 180;
}
}
BindingContext = this;
}
catch (Exception ex)
{
Crashes.TrackError(ex);
}
}
}
}

Delete a ListView item through DisplayActionSheet

I'm creating an ListView App on Visual Studio 2017 Xamarin.forms which shows me a list of my debts. I have added a DisplayActionSheet from "Dispalying Pop-ups" Microsoft Xamarin website. How can I delete a ListView Item on tapped through DisplayActionSheet ?
My DisplayActionSheet look's like this:
private async void DebtsList_ItemTapped(object sender, ItemTappedEventArgs e)
{
var action = await DisplayActionSheet("Details", "Close", null, "Cash", "Delete","");
Debug.WriteLine("Action: " + action);
}
and here is my ListView that shows me all my Debts:
<ListView x:Name="DebtsList"
ItemsSource="{Binding DebtEntries}"
CachingStrategy="RecycleElement"
Grid.Row="7"
Grid.ColumnSpan="3"
Grid.RowSpan="15"
HasUnevenRows="True"
ItemTapped="DebtsList_ItemTapped">
<ListView.Header>
<Grid BackgroundColor="White" Margin="7">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Text="Name" FontSize="11" FontAttributes="Bold" TextColor="#4a4a4a" Grid.Row="0" Grid.Column="0" />
<Label Text="Usage" FontSize="11" FontAttributes="Bold" TextColor="#4a4a4a" Grid.Row="0" Grid.Column="1" />
<Label Text="Value" FontSize="11" FontAttributes="Bold" TextColor="#4a4a4a" Grid.Row="0" Grid.Column="2" HorizontalOptions="End"/>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor="White" Margin="7">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}"
Grid.Row="0"
Grid.Column="0"
FontSize="10"
TextColor="#4a4a4a"/>
<Label Text="{Binding Usage}"
Grid.Row="0"
Grid.Column="1"
FontSize="10"
TextColor="#4a4a4a"/>
<Label Text="{Binding Value}"
Grid.Row="0"
Grid.Column="2"
FontSize="10"
TextColor="#F33E3E"
FontAttributes="Bold"
HorizontalOptions="End"/>
<Label Text="{Binding CreationDate}"
Grid.Row="1"
Grid.Column="0"
FontSize="10"
TextColor="#4a4a4a"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Solution:
private async void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
string result= await DisplayActionSheet("Details", "Close", null, "Cash", "Delete", "");
if(result=="Delete")
{
int position = DebtsList.TemplatedItems.GetGlobalIndexOfItem(e.Item);
mySource.RemoveAt(position);
DebtsList.ItemsSource = mySource;
}
}
mySource is the ItemsSource of the DebtsList,like
public ObservableCollection<DebtEntries> mySource { get; set; }
. . .
mySource = new ObservableCollection<DebtEntries>();
mySource.Add(new DebtEntries { Name = "xxx", Usage="xxx",Value="xxx",CreationDate="xxx"});
//. . .
DebtsList.ItemsSource = mySource;

How can I have a layout take up a percentage of screen space with different orientations?

I'm trying to learn the basics of Xamarin.Forms in preparation for my first project in a few months time. To do this I've tried to make a calculator and I'm currently trying to get the layout right. I want it to have the "Display" take up say 1/4 of the screen and the buttons take up the remaining 3/4 of the screen, and when orientation changes I'd like it to change ratios.
Currently I have sort of accomplished this in portrait view
However when I rotate the screen it looks like this:
I want to be able to move the display bit from the left side to the top of the screen and maybe change it's size so it can accommodate all 4 rows of text.
This is my XAML for the CalcPage.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Calculator.Pages.CalcPage"
Title="Calculator">
<ContentPage.ToolbarItems>
<ToolbarItem Name="Settings" Text="Settings" Priority="0" Activated="Settings_Activated"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout x:Name="MainStack" Spacing="0" >
<StackLayout x:Name="DisplayStack" VerticalOptions="FillAndExpand" Spacing="0">
<Grid x:Name="DisplayGrid">
<Grid.RowDefinitions>
<RowDefinition Height ="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="NumLabel1" Text ="" FontSize="Medium" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="Center" Grid.Row="0"/>
<Label x:Name="OpLabel" Text="" FontSize="Small" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" Grid.Row="1"/>
<Label x:Name="NumLabel2" Text ="" FontSize="Medium" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="Center" Grid.Row="2"/>
<Label x:Name="ResLabel" Text ="" FontSize="Large" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="Center" Grid.Row="3"/>
</Grid>
</StackLayout>
<StackLayout x:Name="ButtonStack" VerticalOptions="FillAndExpand" Spacing="0">
<Grid x:Name="ButtonsGrid">
<Grid.RowDefinitions>
<RowDefinition Height="18*"/>
<RowDefinition Height="18*"/>
<RowDefinition Height="18*"/>
<RowDefinition Height="18*"/>
<RowDefinition Height="18*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Button ClassId="Btn0" Text="0" Clicked="NumBtnClk_Event" Grid.Row="3" Grid.Column="1"
StyleClass="Default"/>
<Button ClassId="Btn1" Text="1" Clicked="NumBtnClk_Event" Grid.Row="2" Grid.Column="0"/>
<Button ClassId="Btn2" Text="2" Clicked="NumBtnClk_Event" Grid.Row="2" Grid.Column="1"/>
<Button ClassId="Btn3" Text="3" Clicked="NumBtnClk_Event" Grid.Row="2" Grid.Column="2"/>
<Button ClassId="Btn4" Text="4" Clicked="NumBtnClk_Event" Grid.Row="1" Grid.Column="0"/>
<Button ClassId="Btn5" Text="5" Clicked="NumBtnClk_Event" Grid.Row="1" Grid.Column="1"/>
<Button ClassId="Btn6" Text="6" Clicked="NumBtnClk_Event" Grid.Row="1" Grid.Column="2"/>
<Button ClassId="Btn7" Text="7" Clicked="NumBtnClk_Event" Grid.Row="0" Grid.Column="0"/>
<Button ClassId="Btn8" Text="8" Clicked="NumBtnClk_Event" Grid.Row="0" Grid.Column="1"/>
<Button ClassId="Btn9" Text="9" Clicked="NumBtnClk_Event" Grid.Row="0" Grid.Column="2"/>
<Button ClassId="Btn+" Text="+" Clicked="OprBtnClk_Event" Grid.Row="0" Grid.Column="3"/>
<Button ClassId="Btn-" Text="-" Clicked="OprBtnClk_Event" Grid.Row="1" Grid.Column="3"/>
<Button ClassId="BtnX" Text="X" Clicked="OprBtnClk_Event" Grid.Row="2" Grid.Column="3"/>
<Button ClassId="Btn/" Text="/" Clicked="OprBtnClk_Event" Grid.Row="3" Grid.Column="3"/>
<Button ClassId="Btn." Text="." Clicked="BtnClkPoint_Event" Grid.Row="3" Grid.Column="0"/>
<Button ClassId="BtnC" Text="AC" Clicked="BtnClkClear_Event" Grid.Row="3" Grid.Column="2"/>
<Button ClassId="Btn=" Text="=" Clicked="BtnClkEquals_Event" Grid.Row="4" Grid.Column="3"/>
</Grid>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
In the C# I have this function for detecting orientation changes.
private double width = 0;
private double height = 0;
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
if(this.width != width || this.height != height)
{
this.width = width;
this.height = height;
}
if(width > height)
{
MainStack.Orientation = StackOrientation.Horizontal;
DisplayStack.VerticalOptions = LayoutOptions.Start;
ButtonStack.VerticalOptions = LayoutOptions.End;
}
else
{
MainStack.Orientation = StackOrientation.Vertical;
}
}
In landscape mode, remove in both Display and Buttons stack the VerticalOptions = FillAndExpand, and add HorizontalOptions = FillAndExpand

How to center a popup in window store app

I have a user control with custom popup (UserHelperButton). I have manually set the Vertical and Horizontal Offset to show popup on the right position. Now I need to update it's position to center. I'm not able to center it on x axis and on vertical.
On the root windows I add add UserHelperButton on different locations
<Grid Margin="0,0,0,25">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<UserControls:UserLabel Text="Varnost v dvoje" Grid.Column="0" />
<UserControls:UserCheckBox x:Name="cbxDouble" Grid.Column="1" cbxClick="cbxDouble_cbxClick" />
<UserControls:UserHelperButton Grid.Column="2" HelperText="V primeru, da se zavarujeta dve osebi, obe zavarovani osebi pridobita nižjo premijo za sklenjena zavarovanja." />
<UserControls:UserLabel x:Name="lblRefNum" Text="Referenčna številka" Grid.Column="3" />
<UserControls:UserCheckBox x:Name="cbxRefNum" Grid.Column="4" cbxClick="cbxRefNum_cbxClick" />
<UserControls:UserTextBox x:Name="txbRefNum" Grid.Column="5" ValidationMessage="Vnesite referenčno številko!" />
<UserControls:UserLabel Text="Zaposlen na Pošta Slovenija" Grid.Column="6" />
<UserControls:UserCheckBox x:Name="cbxPS" Grid.Column="7" cbxClick="cbxPS_cbxClick" />
or
<Grid Margin="0,25,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<UserControls:UserLabel Grid.Column="0" x:Name="lblInsurance" Text="Priporočena varnost do 65. leta" LabelMode="Heading" ValidationMessage="Vsota zavarovanj je premajhna!" />
<UserControls:UserHelperButton x:Name="helper2" Grid.Column="2" />
</Grid>
userControl xaml:
<Grid x:Name="grid" Margin="0" MaxHeight="50" Canvas.ZIndex="4" VerticalAlignment="Center">
<Button x:Name="btnHelper" AutomationProperties.Name="" Style="{StaticResource HelpAppBarButtonStyle}" HorizontalAlignment="Left" VerticalAlignment="Center" Height="70" Click="btnHelper_Click" />
<Popup x:Name="popHelper" IsLightDismissEnabled="True" VerticalOffset="-150" HorizontalOffset="-50">
<Border BorderThickness="25" CornerRadius="25" BorderBrush="Gray" Background="Gray">
<Grid Background="Gray" Width="400" Height="300">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<local:UserLabel Text="Pomoč" LabelMode="Heading" VerticalAlignment="Top" />
<Button x:Name="btnClose" AutomationProperties.Name="" Grid.Row="0" Style="{StaticResource NoAppBarButtonStyle}" HorizontalAlignment="Right" VerticalAlignment="Top" Padding="12,0,0,0" Height="100" Click="btnClose_Click" RenderTransformOrigin="0.5,0.5" >
<Button.RenderTransform>
<CompositeTransform TranslateY="-15"/>
</Button.RenderTransform>
</Button>
<WebView x:Name="webviewControl" Grid.Row="1" Margin="0,20,0,0" Height="200" Width="400" />
</Grid>
</Border>
</Popup>
On load event I fill popup with help text
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
string html = "<html><body style=\"font-family: 'Segoe UI'; background-color: gray; color: white; margin: 0;\">" + g_text + "</body></html>";
var fragment = HtmlFormatHelper.GetStaticFragment(HtmlFormatHelper.CreateHtmlFormat(html));
webviewControl.NavigateToString(fragment);
}
So how can I do that?
Thx
Poki
I do it like this:
private void popup_Loaded(object sender, RoutedEventArgs e)
{
popup.HorizontalOffset = (Window.Current.Bounds.Width - popupGrid.Width) / 2;
popup.VerticalOffset = (Window.Current.Bounds.Height - popupGrid.Height) / 2;
}

Out of memory exception while using <ScrollViewer> with multiple ListViews in it

I have a usercontrol with 2 ListViews in it. One for holding a list of predefined categories and one for the list with all the categories in it.
When i place the ListViews inside a <Grid> than everything works perfect.
The working xaml code (with Grid):
<Grid Style="{StaticResource ResourceKey=ContentStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView x:Name="lstPredefinedCategories" Grid.Row="0" ItemsSource="{Binding PredefinedCategories}" SelectionMode="Multiple" Margin="20">
<ListView.Header>
<StackPanel>
<TextBlock Text="Voorgestelde categorieën" Style="{StaticResource TextBlockStyle}" FontWeight="SemiBold" Foreground="Black" />
<Rectangle Style="{StaticResource DividerStyle}" Fill="Black"/>
</StackPanel>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Style="{StaticResource TextBlockStyle}" HorizontalAlignment="Left" TextWrapping="Wrap" Width="300" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="20,0">
<TextBlock Text="Alle categorieën" Style="{StaticResource TextBlockStyle}" FontWeight="SemiBold" Foreground="Black" />
<Rectangle Style="{StaticResource DividerStyle}" Fill="Black"/>
</StackPanel>
<TextBox x:Name="txtSearch" PlaceholderText="Zoek categorie" Grid.Row="1" Style="{StaticResource SearchboxStyle}" Margin="20,0" TextChanged="txtSearch_TextChanged" />
<Rectangle Grid.Row="2" Style="{StaticResource DividerStyle}" Margin="20, 0" />
<ListView x:Name="lstCategories" Grid.Row="3" Margin="20,10,20,0" ItemsSource="{Binding Categories}" SelectionMode="Multiple" SelectionChanged="lstCategories_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}" Style="{StaticResource TextBlockStyle}" HorizontalAlignment="Left" TextWrapping="Wrap" Width="300" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Rectangle Grid.Row="4" Style="{StaticResource DividerStyle}" Margin="20, 0" />
<Grid Grid.Row="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="btnAnnuleren" Grid.Column="0" Content="Annuleren" Style="{StaticResource ButtonAnnulerenStyle}" Click="btnAnnuleren_Click"/>
<Rectangle Grid.Column="1" Fill="#A9A9A9" Width="0.5" Margin="10,0" />
<Button x:Name="btnSelecteren" Grid.Column="2" Content="Selecteren" Style="{StaticResource ButtonAnnulerenStyle}" Click="btnSelecteren_Click"/>
</Grid>
</Grid>
</Grid>
The only problem with this is that I dont get the UI behaviour that I want. If I use a grid then only the red border is scrollable (because of the ListView). But what I need is that the entire green border is scrollable.
So I want to put everything in a <ScrollViewer><StackPanel></StackPanel></ScrollViewer>.
But when I do so, I occasionally get an out-of-memory exception (sometimes the apps just freezes and close without an exception).
Here is my not working xaml with the <ScrollViewer>:
<ScrollViewer>
<StackPanel>
<ListView x:Name="lstPredefinedCategories" ItemsSource="{Binding PredefinedCategories}" SelectionMode="Multiple" Margin="20">
<ListView.Header>
<StackPanel>
<TextBlock Text="Voorgestelde categorieën" Style="{StaticResource TextBlockStyle}" FontWeight="SemiBold" Foreground="Black" />
<Rectangle Style="{StaticResource DividerStyle}" Fill="Black"/>
</StackPanel>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Style="{StaticResource TextBlockStyle}" HorizontalAlignment="Left" TextWrapping="Wrap" Width="300" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="20,0">
<TextBlock Text="Alle categorieën" Style="{StaticResource TextBlockStyle}" FontWeight="SemiBold" Foreground="Black" />
<Rectangle Style="{StaticResource DividerStyle}" Fill="Black"/>
</StackPanel>
<TextBox x:Name="txtSearch" PlaceholderText="Zoek categorie" Grid.Row="1" Style="{StaticResource SearchboxStyle}" Margin="20,0" TextChanged="txtSearch_TextChanged" />
<Rectangle Grid.Row="2" Style="{StaticResource DividerStyle}" Margin="20, 0" />
<ListView x:Name="lstCategories" Grid.Row="3" Margin="20,10,20,0" ItemsSource="{Binding Categories}" SelectionMode="Multiple" SelectionChanged="lstCategories_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}" Style="{StaticResource TextBlockStyle}" HorizontalAlignment="Left" TextWrapping="Wrap" Width="300" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Rectangle Grid.Row="4" Style="{StaticResource DividerStyle}" Margin="20, 0" />
<Grid Grid.Row="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="btnAnnuleren" Grid.Column="0" Content="Annuleren" Style="{StaticResource ButtonAnnulerenStyle}" Click="btnAnnuleren_Click"/>
<Rectangle Grid.Column="1" Fill="#A9A9A9" Width="0.5" Margin="10,0" />
<Button x:Name="btnSelecteren" Grid.Column="2" Content="Selecteren" Style="{StaticResource ButtonAnnulerenStyle}" Click="btnSelecteren_Click"/>
</Grid>
</Grid>
</StackPanel>
</ScrollViewer>
Any thoughts on why my app is freezing or get an OOM-exception?
Update
It comes because in the 2nd ListView they are too much objects loaded. So I'm gonna try to fix it with ISupportIncrementalLoading.
Or is there an other way?
The solution was to use virtualization (ISupportIncrementalLoading) like suggested in the comments.
Here you can find my implementation class of ISupportIncrementalLoading:
public class StringKeyValueIncrementalCollection : ObservableCollection<StringKeyValue>, ISupportIncrementalLoading
{
private List<StringKeyValue> allCategories;
private int lastItem = 1;
public StringKeyValueIncrementalCollection(List<StringKeyValue> categories)
{
this.allCategories = categories;
}
public bool HasMoreItems
{
get
{
if (lastItem == allCategories.Count)
{
return false;
}
else
{
return true;
}
}
}
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
{
CoreDispatcher coreDispatcher = Window.Current.Dispatcher;
return Task.Run<LoadMoreItemsResult>(async () =>
{
List<StringKeyValue> items = new List<StringKeyValue>();
for (int i = 0; i < count; i++)
{
items.Add(allCategories[i]);
lastItem++;
Debug.WriteLine(lastItem);
if (lastItem == allCategories.Count)
{
break;
}
}
await coreDispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
foreach (StringKeyValue item in items)
{
this.Add(item);
}
});
return new LoadMoreItemsResult() { Count = count };
}).AsAsyncOperation<LoadMoreItemsResult>();
}
}
And then my code in the ViewModel. As you can see, I use the StringKeyValueIncrementalCollection instead of a regular List<object>:
private StringKeyValueIncrementalCollection categories;
private StringKeyValueIncrementalCollection allCategories;
public StringKeyValueIncrementalCollection Categories
{
get { return categories; }
set
{
filteredCategories = value;
RaisePropertyChanged("Categories");
}
}
public async void LoadCategories()
{
List<StringKeyValue> temp = await this.openVlaanderenService.GetCategoriesData();
allCategories = new StringKeyValueIncrementalCollection(temp);
Categories = allCategories;
}
The only problem that you than have is that the ScollViewer will allow it's content to fill as much space as it wants, so the data just will keep loading. To fix that I did what was suggested in ISupportIncrementalLoading inside ScrollViewer not supported?
So I added a SizeChanged="ScrollViewer_SizeChanged" event to my ScrollViewer and in code behind set the size of the ListView based on the viewport size properties of the ScrollViewer:
private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
lstCategories.Height = scrollViewer.ViewportHeight;
}

Categories

Resources