how to optimize windows phone nested list box? - windows-phone-8

here is my data source type
public class Part
{
public int PartNumber { get; set; }
public string ar_PartNumber { get; set; }
public List<PartSuras> PartSuras { get; set; }
public int PageNumber { get; set; }
public string ar_PageNumber { get; set; }
}
public class PartSuras
{
public int SuraID { get; set; }
public string ar_SuraID { get; set; }
public string SuraTitle { get; set; }
public string SuraTitleEn { get; set; }
public int StartVerseID { get; set; }
public int PageNumber { get; set; }
public string ar_PageNumber { get; set; }
}
and here is the nested listboxs
<ListBox Loaded="list_Index_Loaded" Name="list_Index" HorizontalAlignment="Stretch" Margin="-12,-40,-12,0" VerticalAlignment="Top" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate >
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Top">
<Button HorizontalAlignment="Stretch" Width="480" BorderBrush="#FFCADBBD" Margin="0,-12" BorderThickness="0,0,0,2" Background="#FFD2BC70" Foreground="Black" Name="bt_part" Tag="{Binding PageNumber}" Tap="bt_part_Tap" >
<TextBlock HorizontalAlignment="Stretch" TextAlignment="Center">
<Run Text="الجزء "></Run>
<Run Text="{Binding ar_PartNumber}"></Run>
</TextBlock>
</Button>
<ListBox Name="list_sura" ItemsSource="{Binding PartSuras}" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Button HorizontalAlignment="Stretch" Width="480" Margin="0,-12" BorderThickness="0,0,0,2" Background="#FFE5DCAA" Foreground="Black" Name="bt_part" Tag="{Binding PageNumber}" Tap="bt_part_Tap" >
<Grid Width="430" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" TextAlignment="Left">
<Run Text="{Binding ar_SuraID}"></Run>
<Run Text="-"></Run>
<Run Text="{Binding SuraTitle}"></Run>
</TextBlock>
<TextBlock Grid.Column="1" HorizontalAlignment="Stretch" TextAlignment="Right" Text="{Binding ar_PageNumber}"></TextBlock>
</Grid>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
this is kind of slow it takes almost 3 secs to only build the listboxes -i meseured the time of build the data source and it's okay- in Lumia 920 (1 GB ram) device, how can i optimize that?
would the performance be better if i removed the listboxes and created the controls in code behind?

If you do not need scrolling (you have ScrollViewer.VerticalScrollBarVisibility="Disabled"), try using ItemsControl instead, it should perform better.

Use LongListSelector for your outer Listbox and ItemsControl for your inner Listbox. Because LongListSelector is more optimized than ListBox, where as you cannot use a nested longlistselector which leads to scrolling and virtualization problem

Related

Display Data from API on screen in a decent form

i showed API data on screen but in JSON format. Now i want it to look a little bit decent. What changes can i made and in which section.
Here is the API data:
public class myuser
{
public int id { get; set; }
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string avatar { get; set; }
}
}
design Page xaml:
<StackLayout Padding="20">
<Editor Text="id" IsReadOnly="True"/>
<Editor Text="First name" IsReadOnly="True"/>
<Editor Text="Last name" IsReadOnly="True"/>
<Editor Text="Email" IsReadOnly="True"/>
<Image Source="https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg">
</Image>
<Label Text="show json"
x:Name="displaylabel"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
xaml.cs Here i called the API and showed it in JSON format
private static readonly HttpClient client = new HttpClient();
// private String data;
public String show;
//String responseString;
public Data(String data)
{
InitializeComponent();
Task.Run(async () => await GetinfoAsync());
var ID = new Editor { Text = "Id", IsReadOnly = true };
var FirstName = new Editor { Text = "first name", IsReadOnly = true };
var LastName = new Editor { Text = "lastname", IsReadOnly = true };
var Email = new Editor { Text = "email", IsReadOnly = true };
var Avatar = ImageSource.FromUri(new Uri("https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"));
}
public async Task GetinfoAsync()
{
var responseString = await
client.GetStringAsync("https://reqres.in/api/users/2");
show = responseString;
// DisplayAlert("text", responseString, "ok");
Device.BeginInvokeOnMainThread(() => {
displaylabel.Text = show;
});
}
#Sajawal Zubairi
Please try this code it will help you to find your solution:
First, need to install the Newtonsoft.Json package in your project.
XAML Code:-
<StackLayout Padding="20">
<Editor Text="id" IsReadOnly="True"/>
<Editor Text="First name" IsReadOnly="True"/>
<Editor Text="Last name" IsReadOnly="True"/>
<Editor Text="Email" IsReadOnly="True"/>
<Image Source="https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg">
</Image>
<Label Text="show json"
x:Name="displaylabel"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
C# Code:-
public partial class MainPage : ContentPage
{
private static readonly HttpClient client = new HttpClient();
public MainPage()
{
InitializeComponent();
GetinfoAsync();
}
public async Task GetinfoAsync()
{
var responseString = await client.GetStringAsync("https://reqres.in/api/users/2");
myuserResponse result = JsonConvert.DeserializeObject<myuserResponse>(responseString);
// DisplayAlert("text", responseString, "ok");
if (result != null)
{
Device.BeginInvokeOnMainThread(() =>
{
displaylabel.Text = "Id:- " + result.Data.id + "\nEmail:- " + result.Data.email + "\nFirst Name:- " + result.Data.first_name + "\nLast Name:- " + result.Data.last_name + "\nImage:- " + result.Data.avatar;
});
}
}
}
API Data Model :-
public class myuser
{
public int id { get; set; }
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string avatar { get; set; }
}
public class myuserResponse
{
public myuser Data { get; set; }
}
OUTPUT Look like Below Image:
I hope the above code will be useful for you.
Thank You
You can achive your requirement using MVVM approach below is my code will help you
ViewModel code
public class MainPageViewModel : INotifyPropertyChanged
{
private static readonly HttpClient client = new HttpClient();
private UserDTO user;
public UserDTO UserData
{
get { return user; }
set
{
user = value;
OnPropertyChanged();
}
}
public MainPageViewModel()
{
GetUserData();
}
public async Task GetUserData()
{
var responseString = await client.GetStringAsync("https://reqres.in/api/users/2");
UserDTOResponse result = JsonConvert.DeserializeObject<UserDTOResponse>(responseString);
// DisplayAlert("text", responseString, "ok");
if (result != null)
{
UserData = result.Data;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
View(XAML code)
<Grid Margin="20,50">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Editor Grid.Row="0" Grid.Column="0" Text="id" IsReadOnly="True"/>
<Editor Grid.Row="0" Grid.Column="1" Text="{Binding UserData.id}" IsReadOnly="True"/>
<Editor Grid.Row="1" Grid.Column="0" Text="First name" IsReadOnly="True"/>
<Editor Grid.Row="1" Grid.Column="1" Text="{Binding UserData.first_name}" IsReadOnly="True"/>
<Editor Grid.Row="2" Grid.Column="0" Text="Last name" IsReadOnly="True"/>
<Editor Grid.Row="2" Grid.Column="1" Text="{Binding UserData.last_name}" IsReadOnly="True"/>
<Editor Grid.Row="3" Grid.Column="0" Text="Email" IsReadOnly="True"/>
<Editor Grid.Row="3" Grid.Column="1" Text="{Binding UserData.email}" IsReadOnly="True"/>
<Editor Grid.Row="4" Grid.Column="0" Text="Image" IsReadOnly="True"/>
<Image Grid.Row="4" Grid.Column="1" HeightRequest="100" WidthRequest="100" Source="{Binding UserData.avatar}"/>
</Grid>
Models
public class UserDTO
{
public int id { get; set; }
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string avatar { get; set; }
}
public class UserDTOResponse
{
public UserDTO Data { get; set; }
}
Output
enter image description here
I hope it will help you.
Thank you

I am using caliburn micro, but cannot Action in the SelectedItemChanged

My pivotPageViewModel
public class PivotPageViewModel : Conductor<IScreen>.Collection.OneActive
{
private readonly PivotItem1PageViewModel item1;
private readonly PivotItem2PageViewModel item2;
public PivotPageViewModel(PivotItem1PageViewModel item1, PivotItem2PageViewModel item2)
{
this.item1 = item1;
this.item2 = item2;
}
protected override void OnInitialize()
{
base.OnInitialize();
Items.Add(item1);
Items.Add(item2);
ActivateItem(item1);
}
}
PivotItem1
public class PivotItem1PageViewModel : Screen
{
public String DisplayName { get; set; }
public List<String> Item{ get; set; }
public PivotItem1PageViewModel (INavigationService navigationService)
: base(navigationService)
{
DisplayName = "Name";
Item= new List<String>();
Item.Add("one");
Item.Add("two");
Item.Add("three");
Item.Add("four");
}
public void SelectedItemChanged(String select)
{
Debug.WriteLine("HElllo!!! " + select);
}
}
XAML
<ListBox x:Name="Secretariat" Foreground="Black"
FontFamily="{StaticResource PhoneFontFamilyLight}"
FontSize="50" Margin="10,0,-14,0"
cal:Message.Attach="[Event SelectionChanged] = [Action SelectedItemChanged($this)]">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>`
My SelectedItemChanged not work when i use pivotitem, but when i use a page normal the SelectedItemChanged usually work
According Caliburn.Micro documentation :
$this - The actual ui element to which the action is attached
So most likely your select parameter is not a String but ListBox. Do you have any exception from Caliburn about 'action not found'?

How to get values from textbox in a listbox to use in a button?

I'm having trouble with my first application on windows phone 8.
I have a list box, which is being fueled by a json webservice.
need to get the values ​​of textbox to use a button that takes each line of the list box.
an example ... in json webservice I have the values ​​of latitude and longitude ... wanna take those values ​​and use them to open the gps clicking on the button that has the listbox on each line
here s my code
MainPage.xaml
<phone:PhoneApplicationPage
x:Class="JSONParsingExample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!--ContentPanel - place additional content here-->
<Button x:Name="myButton" Grid.Row="0" Height="75" Content="Consulta" VerticalAlignment="Top" />
<ProgressBar Name="ProgressBarRequest" IsIndeterminate="True" Visibility="Collapsed"></ProgressBar>
<StackPanel Name="StackPanelBackground" Height="150"></StackPanel>
<ListBox Name="lbResultado" Grid.Row="2" Grid.ColumnSpan="2">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Width="120" Height="120" Grid.RowSpan="2" Grid.Column="0" Source="{Binding foto1}" Margin="10" VerticalAlignment="Top"></Image>
<TextBox FontWeight="Bold" Foreground="{StaticResource PhoneAccentBrush}" FontSize="20" Text="{Binding nome}" Grid.Row="0" Grid.Column="1" />
<TextBox FontSize="25" Text="{Binding latitude, Mode=TwoWay}" Grid.Row="1" Grid.Column="1" x:Name="txtlatitude" />
<TextBox FontSize="25" Text="{Binding longitude}" Grid.Row="1" Grid.Column="2" Name="longitude" />
<Button x:Name="gps" Grid.Row="2" Grid.Column="2" Height="75" Content="GPS" Click="gps_Click" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</phone:PhoneApplicationPage>
MainPage.xaml.cs
namespace JSONParsingExample
{
public partial class MainPage : PhoneApplicationPage
{
private const string DRIVING_PROTOCOL = "ms-drive-to";
// Constructor
public MainPage()
{
InitializeComponent();
myButton.Click += new RoutedEventHandler(myButton_Click);
}
void myButton_Click(object sender, RoutedEventArgs e)
{
string URL = "link_to_ws"; //working correctly
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri(URL, UriKind.Absolute));
LayoutRoot.Opacity = 0.5;
lbResultado.IsEnabled = false;
}
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
DataContractJsonSerializer json =
new DataContractJsonSerializer(typeof(RootObject));
RootObject lista = (RootObject)json.ReadObject(e.Result);
lbResultado.ItemsSource = lista.wsempresas;
LayoutRoot.Opacity = 1;
lbResultado.IsEnabled = true;
}
public class Wsempresa
{
public string id_empresa { get; set; }
[DataMember(Name = "nome")]
public string nome { get; set; }
[DataMember(Name = "foto1")]
public string foto1 { get; set; }
public string endereco { get; set; }
public string numero { get; set; }
public string bairro { get; set; }
public string cidade { get; set; }
public string estado { get; set; }
public string telefone_comercial { get; set; }
public string website { get; set; }
public string email { get; set; }
[DataMember(Name = "latitude")]
public string latitude { get; set; }
[DataMember(Name = "longitude")]
public string longitude { get; set; }
}
public class RootObject
{
[DataMember(Name = "wsempresas")]
public Wsempresa[] wsempresas { get; set; }
}
void gps_Click(object sender, RoutedEventArgs e)
{
// string latitude = "-20.528430"; this works but i want to get lis box values
//string longitude = "-47.437717";
string uriProtocol = null;
string uri;
// Driving or walking directions?
string buttonClicked = ((Button)sender).Name;
switch (buttonClicked)
{
case "gps":
uriProtocol = DRIVING_PROTOCOL;
break;
default:
uriProtocol = DRIVING_PROTOCOL;
break;
}
// Assemble the Uri for the request.
uri = uriProtocol + ":?" +
"destination.latitude=" + latitude + "&" +
"destination.longitude=" + longitude + "&" ;
//"destination.name=" + SEATTLE_NAME;
// Make the request.
RequestDirections(uri);
}
async void RequestDirections(string uri)
{
// Make the request.
var success = await Windows.System.Launcher.LaunchUriAsync(new Uri(uri));
if (success)
{
// Request succeeded.
}
else
{
// Request failed.
}
}
}
}
can you help me please?
You can try to get latitude and longitude value using Button's DataContext :
void gps_Click(object sender, RoutedEventArgs e)
{
Wsempresa wsempresa = (Wsempresa)((Button)sender).DataContext;
string latitude = wsempresa.latitude;
string longitude = wsempresa.longitude;
.........
.........
}

How to de-serialize json in c#?

I am trying to deserialize json, I'm getting an error:
"An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.DLL but was not handled in user code"
My code:
public void w_StandingsDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Result))
{
JsonSerializer jc = new JsonSerializer();
// var o = jc.Deserialize<RootObjectStandings>(e.Result);
var root3 = JsonConvert.DeserializeObject<RootObjectStandings>(e.Result);
// var root2 = JsonConvert.DeserializeObject<Headline>(e.Result);
football f = new football();
f.StandingList.ItemsSource = root3.info;
f.progressbar1.IsEnabled = false;
f.progressbar1.IsIndeterminate = false;
f.progressbar1.Visibility = Visibility.Collapsed;
}
}
Class:
public class RootObjectStandings
{
public int position { get; set; }
public int team_id { get; set; }
public string team { get; set; }
public string teamshort { get; set; }
public string teampath { get; set; }
public int played { get; set; }
public int won { get; set; }
public int drawn { get; set; }
public int lost { get; set; }
public int #for { get; set; }
public int against { get; set; }
public int difference { get; set; }
public Home home { get; set; }
public Away away { get; set; }
public int points { get; set; }
public string info { get; set; }
}
and xaml code:
<ListBox x:Name="StandingList" FontFamily="Arial Black" VerticalAlignment="Center" Margin="-6,0,0,-26" Height="610" RenderTransformOrigin="0.5,0.5" Background="{x:Null}" Opacity="0.8">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Button Style="{StaticResource ButtonStyle1}" Width="450" Height="Auto" Background="Black" BorderBrush="Transparent" FontWeight="Bold" FontSize="23" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,5" Opacity="0.95" Foreground="White">
<StackPanel>
<TextBlock TextWrapping="Wrap" FontFamily="Segoe WP Black" Foreground="White" FontSize="18" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TextAlignment="Left" Width="350" Height="150">
<Run FontSize="23" Text="{Binding info}" />
<LineBreak/>
<Run Text="{Binding position}" FontWeight="Normal" FontSize="16" FontFamily="Segoe WP SemiLight"/>
</TextBlock>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What is going wrong? help

Bind ImageSource in Windows Phone

I am Using LazyListBox as given below.There is an Image in Data Template.And I am not able to Bind the ImageUrl.How can i Bind ImageSource.
<lazy:LazyListBox x:Name="d" ItemSource={Binding ProductImageLIst}>
<lazy:LazyListBox.LoadedItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Product_Id}" Foreground="Black"></TextBlock>
<Image x:Name="img" Source="{Binding Path=ImageUrl}"></Image>
</StackPanel>
</DataTemplate>
</lazy:LazyListBox.LoadedItemTemplate>
</lazy:LazyListBox>
And my ProductImageList Class is Shown Below
public class ProductImageList
{
public string ImageId { get; set; }
public string ImageUrl{ get; set; }
public string Product_Id { get; set; }
public string Category_id { get; set; }
public ProductImageList()
{
}
public ProductImageList(string imageid, string imageurl, string productid,string catid)
{
this.ImageId = imageid;
this.ImageUrl = imageurl;
this.Product_Id = productid;
this.Category_id = catid;
}
}
Use BitmapImage to bind source of image in LazyListBox control. Here is the solution. If your 'ImageUrl' is a http url you should first download image from this url and create BitmapImage by downloaded image stream, and if your imageUrl is a relative url create BitmapImage as below.
<lazy:LazyListBox x:Name="d" ItemSource={Binding ProductImageLIst}>
<lazy:LazyListBox.LoadedItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Product_Id}" Foreground="Black"></TextBlock>
<Image x:Name="img" Source="{Binding Path=ImageSource}"></Image>
</StackPanel>
</DataTemplate>
</lazy:LazyListBox.LoadedItemTemplate>
</lazy:LazyListBox>
public class ProductImageList
{
public string ImageId { get; set; }
public string ImageUrl{ get; set; }
public string Product_Id { get; set; }
public string Category_id { get; set; }
public BitmapImage ImageSource{get;set;}
public ProductImageList()
{
}
public ProductImageList(string imageid, string imageurl, string productid,string catid)
{
this.ImageId = imageid;
this.ImageUrl = imageurl;
this.Product_Id = productid;
this.Category_id = catid;
this.ImageSource = new BitmapImage(new Uri(imageurl, UriKind.RelativeOrAbsolute));
}
}