LongListSelector Load items Infinite - windows-phone-8

For my windows phone 8 app, my data provider provides 10 items per page and i have to show the results in a LongListSelector.
My first challenge is that it provides data in JSON that i parse to array, so i cannot easily add items in my longlistselector.ItemsSource. Well, will do it somehow by observableCollection.
Second challenge is when user scrolls down to 8th or 9th item i have to load page 2 and so on until it returns items less than 10.
I am done with ItemRealized event, it is called for all 10 items at load so if i load page 2 it will load all the pages before screen loading.
I have checked the TwitterSearch example msdn has but unfortunately its api is expired. Any help?
EDIT
For my test projects, item template is below.
<phone:LongListSelector.ItemTemplate>
<DataTemplate >
<ListBoxItem Margin="20">
<TextBlock FlowDirection="LeftToRight" Text="{Binding}" Margin="0,10,0,0" Foreground="#343330" FontSize="24"/>
</ListBoxItem>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
and the binding is below.
ObservableCollection<string> data = new ObservableCollection<string>();
.
.
.
IsLoading = true;
for (int i = 0; i < 10; i++)
data.Add(string.Format("item {0}", (pageNo * 10) + (i + 1)));
pageNo++;
IsLoading = false;
itemRealized event is given below
private void LongListSelector_ItemRealized(object sender, ItemRealizationEventArgs e)
{
//data.ItemCount = data.ItemCount + 1;
itemCount++;
if (itemCount < 100
&& reloadOnItem.Contains(itemCount))
{
loadData();
}
}

Related

Windows Phone 8.1 live tile not updating daily

I'm having problems to get my Windows Phone 8.1 live tile update by itself daily (around 7am)
My project has 2 parts :
a Web API project hosted on Azure that provides the tile template in XML (that part works fine)
a Windows Phone 8.1 project with a single MainPage.xaml where I build 2 square/wide tiles
When I pin my app to the start screen from the app list, my tile (whether I choose the square or wide format) flips back and forth between my 2 brands of the day just fine.
The next morning at 7:15 am, the tile won't update with the 2 new brands :(
I noticed that if I tap the tile to launch the app and come back to the start screen, the tile has updated.
It also works if I unpin and repin the tile but in both cases, that's "cheating" :-/
I call my Azure website like this to get the tile templates of both brands :
http://example.azurewebsites.net/api/tiles/0 (BRAND1)
http://example.azurewebsites.net/api/tiles/1 (BRAND2)
The XML tile template looks like this (example):
<tile>
<visual>
<binding template="TileWide310x150ImageAndText01">
<image id="1" src="http://www.example.com/sales/BRAND1/visualWide.png"/>
<text id="1">Brand 1</text>
</binding>
<binding template="TileSquare150x150PeekImageAndText04">
<image id="1" src="http://www.example.com/sales/BRAND1/visualSquare.png"/>
<text id="1">Brand 1</text>
</binding>
</visual>
</tile>
The WP8.1 page contains this :
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
TileUpdateManager.CreateTileUpdaterForApplication().EnableNotificationQueue(true);
PeriodicUpdateRecurrence recurrence = PeriodicUpdateRecurrence.Daily;
Task<string> responseBody;
for (int i = 0; i < 2; i++)
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("http://xxxxx.azurewebsites.net/api/tiles/" + i); //I hid the address here for discretion
HttpResponseMessage response = httpClient.GetAsync(httpClient.BaseAddress).Result;
string statusCode = response.StatusCode.ToString();
response.EnsureSuccessStatusCode();
responseBody = response.Content.ReadAsStringAsync();
}
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(responseBody.Result);
string srcWide, srcSquare, textWide, textSquare, templateWide, templateSquare;
XElement root = XElement.Parse(responseBody.Result);
IEnumerable<XElement> wideElement = root.Descendants("binding").Where(a => a.Attribute("template").Value.ToLower().Contains("wide"));
IEnumerable<XElement> squareElement = root.Descendants("binding").Where(a => a.Attribute("template").Value.ToLower().Contains("square"));
templateWide = wideElement.Attributes("template").SingleOrDefault().Value;
srcWide = wideElement.Descendants("image").Attributes("src").SingleOrDefault().Value;
textWide = wideElement.Descendants("text").SingleOrDefault().Value;
templateSquare = squareElement.Attributes("template").SingleOrDefault().Value;
srcSquare = wideElement.Descendants("image").Attributes("src").SingleOrDefault().Value;
textSquare = wideElement.Descendants("text").SingleOrDefault().Value;
XmlDocument wideTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileWide310x150ImageAndText01);
XmlNodeList wideTileTextAttributes = wideTileXml.GetElementsByTagName("text");
wideTileTextAttributes[0].InnerText = textWide;
XmlNodeList wideTileImageAttributes = wideTileXml.GetElementsByTagName("image");
((XmlElement)wideTileImageAttributes[0]).SetAttribute("src", srcWide);
((XmlElement)wideTileImageAttributes[0]).SetAttribute("alt", textWide);
XmlDocument squareTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150PeekImageAndText01);
XmlNodeList squareTileTextAttributes = squareTileXml.GetElementsByTagName("text");
squareTileTextAttributes[0].AppendChild(squareTileXml.CreateTextNode(textSquare));
XmlNodeList squareTileImageAttributes = squareTileXml.GetElementsByTagName("image");
((XmlElement)squareTileImageAttributes[0]).SetAttribute("src", srcSquare);
((XmlElement)squareTileImageAttributes[0]).SetAttribute("alt", textSquare);
IXmlNode node = wideTileXml.ImportNode(squareTileXml.GetElementsByTagName("binding").Item(0), true);
wideTileXml.GetElementsByTagName("visual").Item(0).AppendChild(node);
TileNotification tileNotification = new TileNotification(wideTileXml);
tileNotification.ExpirationTime = DateTimeOffset.UtcNow.AddDays(1).AddHours(7).AddMinutes(0);
TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);
}
List<Uri> urisToPoll = new List<Uri>(5);
urisToPoll.Add(new Uri("http://example.azurewebsites.net/api/tiles/0")); //fake url
urisToPoll.Add(new Uri("http://example.azurewebsites.net/api/tiles/1")); //fake url
//I want the tile to update its content every day at 7:15am
//(the Azure website supposedly returns new brands of the day at 7am)
DateTime dtTomorrow7 = DateTime.SpecifyKind(DateTime.Today.AddDays(1).AddHours(7).AddMinutes(15), DateTimeKind.Local);
DateTimeOffset dtoTomorrow7 = dtTomorrow7;
TileUpdateManager.CreateTileUpdaterForApplication().StartPeriodicUpdateBatch(urisToPoll, dtoTomorrow7, recurrence);
}
I'm not sure I'm using the StartPeriodicUpdateBatch method correctly.
In debug mode,I can see the DateTimeOffset value is Day+1 7:15am +2:00 which looks correct but the tile does not update.
I live in France that is UTC+2
Thanks for your suggestions.
Your dtTomorrow7 is incorrect. It should just be 7:15 AM. Then it will first do an update at 7:15 AM and subsequent updates occurring at the periodic interval thereafter(you set it to daily).
Example of start time where the last TimeSpan is offset from UTC:
DateTime tomorrow = DateTime.Today.AddDays(1);
var startTime = new DateTimeOffset(tomorrow.Year, tomorrow.Month, tomorrow.Day, 7, 15, 0, TimeSpan.FromHours(2));

A first chance exception of type 'System.ArgumentException' while creating dynamic pivot item

I am trying to create pivot item dynamically,
here the code which i used
paginationPivot.Items.Clear();
for (int i = 1; i <= pagecount; i++)
{
TextBlock textBlock = new TextBlock();
textBlock.Foreground = new SolidColorBrush(Colors.Blue);
textBlock.FontSize = 30;
textBlock.Text = (i).ToString();
Border border = new Border();
PivotItem pivotItem = new PivotItem() { Name="item"+i.ToString(), Header=textBlock, Content=border,Margin= new Thickness(0,-70,0,0), FlowDirection=System.Windows.FlowDirection.RightToLeft};
paginationPivot.Items.Add(pivotItem);
}
here the error which i got
A first chance exception of type 'System.ArgumentException' occurred in Microsoft.Phone.ni.dll
Can anybody please help me to solve this issue.
Thank you.
but i got this error while while creating pivot item
You can't set directly "Header=textBlock", just using a string hold content that you want to show.
E.g: Header="header 1".
If you want to use more complex UI, let's use HeaderTemplate:
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<StackPanel Background="#666666" Margin="0">
<TextBlock FontSize="30" Foreground="Blue" Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</controls:Pivot.HeaderTemplate>
And after that:
<controls:PivotItem Header="header 1">
</controls:PivotItem>

How to select all items in windows phone list picker

I have windows phone list picker Control in my code I bind the items from c#.i.e, items comes from services .I have to keep "select all" item .so that i can select all the items at once.I added "select all" .On checking the "Select All" check box .I could not get any event to execute the code so that all check boxes are checked and UI get reflected
Thanks in advance
Try this code
private void SelectAll(object sender, RoutedEventArgs e)
{
yourlistbox.SelectAll();
}
For more information check out the documentation in msdn http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.selectall%28v=vs.110%29.aspx
Im not sure if this the right way, But this works
List<object> arr = new List<object>((((System.Collections.Generic.Dictionary<string, string>)(s))).Values);
for (int k = 0; k < data.Length; k++)
{
object selectitem = arr[k];
items.Add(selectitem);
}
yourlistbox.SelectedItems = items;
This is how i made it work in my case so the way is to create a list object containing all elements from your data source and assigning to to selected items.
I think this can be done with LongListMultiSelector
See here
http://channel9.msdn.com/Series/Windows-Phone-8-Development-for-Absolute-Beginners/Part-31-Multiple-Selection-with-the-LongListMultiSelector
http://winphone8dev.blogspot.in/2012/12/longlistmultiselector.html?m=1

Method 'Boolean Contains(System.DayOfWeek)' has no supported translation to SQL

In my Windows Phone Mango app, I have a bunch of checkboxes, each corresponding to a day of the week. I want to filter the data I query by which checkboxes are checked. Here's what I've come up with, but I feel like there's a better solution:
Declare the checkboxes in XAML:
<CheckBox Content="Mon" x:Name="MonCheckbox" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap"/>
<CheckBox Content="Tue" x:Name="TueCheckbox" Grid.Column="1" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Wed" x:Name="WedCheckbox" Grid.Column="2" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Thur" x:Name="ThurCheckbox" Grid.Row="1" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Fri" x:Name="FriCheckbox" Grid.Row="1" Grid.Column="1" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Sat" x:Name="SatCheckbox" Grid.Row="1" Grid.Column="2" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
<CheckBox Content="Sun" x:Name="SunCheckbox" Grid.Row="2" Grid.Column="0" Checked="DayCheckbox_Tap" Unchecked="DayCheckbox_Tap" />
Associate a day with each checkbox:
public MainPage()
{
InitializeComponent();
LayoutRoot.DataContext = this;
// This is grossly imperative. Can it be done in XAML?
MonCheckbox.Tag = DayOfWeek.Monday;
TueCheckbox.Tag = DayOfWeek.Tuesday;
WedCheckbox.Tag = DayOfWeek.Wednesday;
ThurCheckbox.Tag = DayOfWeek.Thursday;
FriCheckbox.Tag = DayOfWeek.Friday;
SatCheckbox.Tag = DayOfWeek.Saturday;
SunCheckbox.Tag = DayOfWeek.Sunday;
// ...
}
Maintain a collection of the currently selected days:
ICollection<DayOfWeek> _selectedDays = new Collection<DayOfWeek>();
private void DayCheckbox_Tap(object sender, RoutedEventArgs e)
{
CheckBox checkbox = (CheckBox)sender;
if (_selectedDays.Contains((DayOfWeek)checkbox.Tag))
{
_selectedDays.Remove((DayOfWeek)checkbox.Tag);
}
else
{
_selectedDays.Add((DayOfWeek)checkbox.Tag);
}
refreshCheckinData();
}
The problem comes when I go to refresh the data that's displayed to the user:
private void refreshCheckinData()
{
Checkins.Clear();
Checkins.AddAll(from checkin in checkinData.Items
where _selectedDays.Contains(checkin.DateTime.DayOfWeek)
select checkin);
}
public static class ExtensionMethods
{
public static void AddAll<T>(this ICollection<T> dest, IEnumerable<T> source)
{
if (dest == null)
{
throw new ArgumentNullException("dest");
}
foreach (T t in source)
{
dest.Add(t);
}
}
}
When the code tries to iterate over source in AddAll(), the following exception occurs:
Method 'Boolean Contains(System.DayOfWeek)' has no supported translation to SQL." System.Exception {System.NotSupportedException}
How can I get around this? Why does Contains require a SQL translation? Is there a better approach to this whole thing, using more declarative XAML and less imperative code-behind?
Update: I tried changing the query to:
where _selectedDays.Any(day => day == checkin.DateTime.DayOfWeek)
now I get the following error:
"Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator." System.Exception {System.NotSupportedException}
_selectedDays is defined in memory. why does it need to be translated to SQL?
Your original query is close. I think the Contains() method on ICollection is getting in the way of the SQL translator -- I would need to double check the code to be sure.
You can work around this by forcing selection of the Enumerable.Contains() extension method by changing your code to this:
private void refreshCheckinData()
{
Checkins.Clear();
Checkins.AddAll(from checkin in checkinData.Items
where _selectedDays.AsEnumerable().Contains(checkin.DateTime.DayOfWeek)
select checkin);
}
Enumerable.Contains(T) extension method will translate into an IN clause in the database.
The resulting query will be something like this:
SELECT [t0].[Key], [t0].[Day]
FROM [Stuff] AS [t0]
WHERE [t0].[Day] IN (#p0, #p1)
If i understand it correctly then you wanna add all selected days to your 'Chekings' so why don't you try this code, i think this will solve your problem for now and to answer the other questions i have to think about them a bit a do some research. :)
foreach(var day in _selectedDays)
{
Checkins.AddAll(from checkin in checkinData.Items
where checkin.DateTime.DayOfWeek == day
select checkin);
}
Would have to test this one i don't know if it works or not or if it is even valid.
from checkin in checkinData.Items
join sdays in _selectedDays on checkin.DateTime.DayOfWeek == sdays
select checkin

HTMLTextBlock for Windows Phone 7

I am trying to include a html textbox into my windows phone 7. I see some sample code here. The problem is that the HTMLPage class doesn't exist in windows phone 7, or more exactly, the System.Windows.Browser does not exist. Do anybody know an alternative for this?
I struggled with this for all the same reasons, and eventually came up with a solution. I need to show a bunch of these inside a ListBox for my Septic's Companion app. Right now my solution only deals with bold or italic (as that's all I cared about) but it would be easy to modify it to deal with more. First, into my ViewModel I wrote a routine to return a TextBlock given an HTML string.
private TextBlock MakeFormattedTextBlock(string shtml)
{
TextBlock tb = new TextBlock();
Run temprun = new Run();
int bold = 0;
int italic = 0;
do
{
if ((shtml.StartsWith("<b>")) | (shtml.StartsWith("<i>")) |
(shtml.StartsWith("</b>")) | (shtml.StartsWith("</i>")))
{
bold += (shtml.StartsWith("<b>") ? 1 : 0);
italic += (shtml.StartsWith("<i>") ? 1 : 0);
bold -= (shtml.StartsWith("</b>") ? 1 : 0);
italic -= (shtml.StartsWith("</i>") ? 1 : 0);
shtml = shtml.Remove(0,shtml.IndexOf('>') + 1);
if (temprun.Text != null)
tb.Inlines.Add(temprun);
temprun = new Run();
temprun.FontWeight = ((bold > 0) ? FontWeights.Bold : FontWeights.Normal);
temprun.FontStyle = ((italic > 0) ? FontStyles.Italic : FontStyles.Normal);
}
else // just a piece of plain text
{
int nextformatthing = shtml.IndexOf('<');
if (nextformatthing < 0) // there isn't any more formatting
nextformatthing = shtml.Length;
temprun.Text += shtml.Substring(0, nextformatthing);
shtml = shtml.Remove(0, nextformatthing);
}
} while (shtml.Length > 0);
// Flush the last buffer
if (temprun.Text != null)
tb.Inlines.Add(temprun);
return tb;
}
Then I just needed a way to build this into my XAML. This may not be the very best solution, but I first made another routine to return a StackPanel containing that TextBlock with the text I wanted.
public StackPanel WordBlock
{
get
{
StackPanel sp = new StackPanel();
TextBlock tbWord = MakeFormattedTextBlock("<b>" + Word + "</b>: " + Desc);
sp.Children.Add(tbWord);
return sp;
}
}
To bind this to a visible control, I then made a DataTemplate for my ListBox which simply read the entire StackPanel out of my view model.
<DataTemplate x:Key="WordInList2">
<ContentControl Content="{Binding WordBlock}"/>
</DataTemplate>
As I say, there may be parts of this that aren't done as elegantly as they might be, but this did what I wanted. Hope it works for you!
Hey I converted the SilverlightHtmlTextBlock to WP7 Here. I
haven't tested it for terribly complex cases and blows up on dtd tags but, it does the job for simpler html cases and sounds like what you were looking for.
WebBrowser can render html.
How to: Display Static Web Content Using the WebBrowser Control for Windows Phone