Bulk Data with images in LongListSelector - c#

Following is one screen of my app that loads around 100 items on each search call to server (WCF).
I have two following questions.
One: currently i am assigning all the resultant items to itemssource of longlist selector but i want to load initially 10 items and when user swipes down to almost end it load 10 more. have seen this behavior in many applications (foursquare) but couldn't figure out because i am new for silverlight.
Two: If the item has image then PicturePath is set to the server image path otherwise local no-image path is set. Problem is when image is being downloaded the image area is shown blank until it fully downloads and then starts showing images, i need it be be something like foursquare shows until image is completely loaded. My binding code is given below along with my requirement.
Thanks.

Makes no sense to answer both questions with a bunch of code.
Regarding the first question, you need a way to detect when the user has scrolled to the bottom of the ListBox / LongListSelector. You need to use ObservableCollection instead of a simple List, because ObservableCollection notifies the UI when the new items are added to it.
This question has been asked dozens of times before, for example see here.
Regarding the second question, the simplest solution would be to use two images, one on top of the other inside the ItemTemplate. That way the static, local image will be shown while the dynamic is empty, and when the dynamic one is downloaded it will cover the static one. It's rendered on top of the static image so it's as if the static image was not there.
<Grid>
<Image Source="Assets/StaticImageFromLocalCache.jpg" Width="400" Height="400" />
<Image Source="Assets/DynamicImageFetchedFromInternet.jpg" Width="400" Height="400" />
</Grid>

Related

How to extend text selection across text blocks in a UWP app

My app has a bunch of paragraphs which are compared together. This is implemented using a generic ItemsRepeater that creates as many Grid elements as there are paragraphs. Inside each grid is a TextBlock with the paragraph number, and a RichTextBlock that contains the paragraph. The hierarchy is therefore like this:
<ItemsRepeater>
<Grid>
<TextBlock />
<RichTextBlock></RichTextBlock/>
</Grid>
<Grid>
...
</Grid>
<Grid>
...
</Grid>
</ItemsRepeater>
This results in a text selection as follows:
Only one RichTextBlock can be selected at a time. However, I would like to allow text selection of all paragraphs of the ItemsRepeater. How is that possible?
Edit
I'm open to other approaches. I've tried manually filling in a StackPanel or RichTextBlock with items. That's not a problem. However, because the numbered paragraphs need to align, I need to be able to set their height to match each other. From what I can find, only elements that derive from FrameworkElement have the ActualHeight and Height properties I need for that. However, FrameworkElements like TextBlock and RichTextBlock also do not allow multiple selection, which is the problem I'm trying to solve in the first place. Someone posted a response to a similar question about WPF, but it uses a strange solution I don't think applies.
So the question could also be framed as: how is it possible to find and set the height of a Run within a TextBlock or RichTextBlock? Using that idea, it was impossible to get/set the run height inside a paragraph. I'm not bound to using ItemsRepeater, but that has also not yielded a useful result. I'm seeking to avoid resorting to HTML/Javascript for this.
UWP does not expose enough APIs for you to do that. I have worked on a similar issue with RichEditBox on UWP and there is no good solution that I have found. But if you really want to, there are two main approaches to achieve that:
Implementing the selection yourself by sniffing the mouse events and render the selection on top of the controls. There are so many corner cases, specially if you want to have a proper accessibility tree for the control that you are building.
Alternatively, you can create a WinRT C++ project where you would have access to more APIs, build a control and render it onto a canvas that is created with your C#/Xaml app.
The good news is that you are not permitting people to edit (RichTextEdit) and it is just view (RichTextBlock) so you do not have to worry about the automatic corrections, IME, Url detection, etc.
Edit: Originally I mentioned WinRT C++, but I meant C++/CX. It might work with WinRT too, but I have not tried.

Windows Store App ListView flickering / content dispappearing

I have some trouble with ListView where the ItemsSource can be very important (over 5'000 items).
My application is that of a Chat Application consisting of two ListViews.
One on the left, the thread ListView showing a list of active thread
(conversation)
One on the right, the conversation ListView showing all messages exchanged.
I am using the DataTemplatepattern so that each item of my conversation ListView is customized as follow :
A chat Bubble using Coding4Fun package : http://www.geekchamp.com/articles/getting-started-with-the-coding4fun-toolkit-windows-phone-chatbubble-control
Each Chat Bubble has two TextBlock (one for the message content, the other for the timestamp).
Later, I intend to add pictures to this messages.
When user clicks on a conversation from the left-panel ListView, the main conversation ListView is loaded with the corresponding conversation (observable) collection.
If that collection is particularly big (in one case, I have more than 10'000 messages), the conversation ListView does show the content, but as soon as a switch to another thread and back to the previous, the content does not show anymore, although it's here, it's loaded. Starting to scroll, makes the ListView flickering and the content, therefore, is visible but severly flickering. If I stop scrolling, no content is showed, showing an empty list.
Further tests showed that this problem occurs only with large collection in concordance of usage of ScrollIntoView() method: indeed, I whish to show the bottom of my conversation ListView each time a user clicks on a thread so that he can read the last messages instead of the oldes, therefore saving him to have to scroll all the way to the bottom, each time.
I confirmed this issue by commenting out the line where I make the ListView to scroll to the bottom. The flickering problem is gone.
Finally, as I wrote my question, I found a stackoverflow question that seems to be my case: Windows Store universal app - ListView oddity
Unfortunately, the solution is not very clear. How can I solve my issue ? How should I use VirtualizingStackPanel/>inside a ListView that uses alread <ListView.ItemContainerStyle>, ListView.ItemTemplate>and <DataTemplate> ?
The solution to my flickering problem and how to implement UI Virtualization (normaly introduced in Windows 8.1) as described here https://www.microsoftpressstore.com/articles/article.aspx?p=2216995&seqNum=4 is as follow :
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
To be placed within a ListView scope !
Orientation must be defined ( Vertical | Horizontal ) otherwise a Critial Failure occurs !
UI Virtualization enhance large GridViews and ListViews so that huge amount data can be effeciently loaded without slowing down the UI nore blocking it for too long.
Honnestly the answer to your problem would be to redesign your application.
Never should there be so many items in a listview. You need to filter out some results
Example : Sort the question names /types/ etc and only show the corresponding (such as tags in Stack Overflow)
Only show the last lines of the conversation when you load it and allow the user to load more (like facebook's messenger)
Take a look at this C# listview maximum number of rows
As the answer says. The amount of items in your listview should be limited by common sense. 5k items in one listview is an incredibly high amount for a user to scroll through.
I am assuming your bubbles are in some kind of list or array. You can use Linq to get what you want. Take a look at this LINQ query to select top five

How to properly make custom templates which are images in xaml

I was assigned a very obscure project where basically every control, every design element is an image. I was provided with design files for every element of the app.
I even informed the people who gave the assignment that it's probably a very bad idea due to many different reasons, and it would be better to do everything manually but I still have to do it with images. Every time I add something - I see that everything is fine in the designer , but when I run it on my Lumia 925 everything shifts a little bit in different directions, even the buttons.
Any suggestions on the proper way to do this? To have custom templates for buttons which are basically images in a way it will not shift and I would see the same thing in the designer and on the device.
You have a great solution for controls called Behaviors, just add the extension in the project and add the following everywhere you need a Tap like the following, (that's an example just for tap you could use the event tap):
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
<Image>
<Interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Tapped">
<core:CallMethodAction .../>
</core:EventTriggerBehavior>
...
</Interactivity:Interaction.Behaviors>
You have all the behaviors and actions here:
https://msdn.microsoft.com/en-us/library/microsoft.xaml.interactions.core.aspx
and how to add them in the project here:
http://blogs.windows.com/buildingapps/2014/07/22/tips-and-tricks-for-using-xaml-controls-in-your-universal-windows-apps/
Then add the logic in the methods you call from the images. There are plenty of behaviors done, to begin storyboards, to change properties...
Apart you can use a ViewBox control that it scales everything in the screen to not be scaling every image. Try that.

Why doesn't a new View get created when I create new ViewModel

I have a MVVM trading application.
MainView has two tab controls - left one displays a collection of "workspaces" and the right one displays dynamic data display charts.
When I create the first "chartviewmodel" the correct chart appears in the right tab control as expected.
When I then create another "chartviewmodel" with different data that should result in a different chart, that's not what happens. The second tab item is a duplicate of the first from a visual standpoint. The tab items are contained in a collection of items called: "chartspaces" and in debug mode I can see each viewmodel and indeed each has different values.
Also, in debug mode I put a breakpoint on the "Initialize()" method of the view and when the first chartviewmodel is created, that method indeed gets called. When I then create the second chartviewmodel, the "Initialize()" method is not called, so in fact another view is not getting created...but I can't figure out why.
My view/viewmodel's are tied together via DataTemplate with x:Shared="False" (tried it with and without this parameter). I've traced through the constructor of the chartviewmodel to ensure it was not getting any errors and it is not.
On the left-most tab control, I can create multiple tradeviewmodel and each results in a different view... in other words it is behaving as expected.
My XAML for the right tab control is essentially the same as for the left one with the exception of the "workspace" collection (left uses "workspaces" right uses "chartspaces" so I'm at a loss as to what might be wrong or how to diagnose this problem further.
The datatemplate looks like:
<DataTemplate x:Shared="False" DataType="{x:Type vm:ModelOptionChainViewModel}">
<vw:DDDRiskChart />
</DataTemplate>
In further experimenting, I put the tab items on the left side instead and found the same problem, but if I selected a non-Dynamic Data Display tab item, then one of the DDD charts, they display correctly. So, before I selected a DDD chart I had to display a non-DDD chart, then the DDD chart for it to display.
So, moving the tab items back to the right tab control, I put the two DDD charts in, then put in a non-DDD chart (a DataVisualization chart). I found the same behavior...if I selected the non-DDD chart and then the DDD chart, it displays correctly. If I just alternate between the two DDD charts, they will both display the same graph! Is that not weird?
So, for any of you who care...the problem is actually associated with the TabControl behavior.
Irv Krivyakov has an excellent Code Project with description (link:
http://www.codeproject.com/Articles/460989/WPF-TabControl-Turning-Off-Tab-Virtualization )
that describes the problem AND provides a TabContent behavior class that eliminates the problem. The crux of the problem has to do with virtualization within TabControl. Rather than repeat his explanation, please see the above link. Also, see:
DataTemplate x:Shared=false has no impact on the view
especially the last post on that thread as it discusses TabControl and DataTemplate behaviors.
My fix was:
use Irv Krivyakov's TabContent behavior and my TabControl now looks like:
<DataTemplate x:Key="ChartspacesTemplate">
<TabControl
Name="chartTab"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
behaviours:TabContent.IsCached="True" // THIS IS THE FIX!!
ItemTemplate="{StaticResource ChartTabItemTemplate}"
Margin="4"
/>
Note: the one line change. Now when I switch tabs the correct data shows.

What component should i use instead of listbox?

My app shows newsfeed from social network. Every feed has different attachments - images, video, audio, etc, - so every feed has different height. Newsfeed shows in listbox using template selector. I read MSDN and as i can see - i broked almost all rules how to use listbox (non fixed sized items, nested listboxes, and so on). As result - i have laggin listbox, which jumping from item to item when it wants. So, if MS couldn't make a listbox, which can normaly works with dynamic items, what sould i use to get smooth scrolling by items?
UPD: Why minuses? Can you explain? Its a bad question? I think not only for me its important.
You can try the ItemPresenter control with a ItemTemplate.
You could try stackpanel inside a scrollviewer.
Also you could make images and text load only when scrollviewer gets close to displaying that item, not load everything all the way at the start.
This reduces internet traffic, loading time and the lag while scrolling. Ofcourse it will take some of your coding time, but believe me - it will be well worth it! Most services use this thus cutting server load and traffic.
Check if that helps!

Categories

Resources