I have Listview with templated items (which looked just like Windows Explorer). My problem is when I openning folder which contains a whole lot of files that ListView loads those files not smoothly.(see video: http://screencast.com/t/bY7ucELj9I).
Does someone has any idea how to solve it?
You may need to virtualize your ListView's Items. Example
<ListView Name="ListViewWithVirtualization" Height="100" Margin="5"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling" />
If you set VirtualizingStackPanel.VirtualizationMode = “Recycling” then each container will get reuse instead of destroy. You will get better performance by specifying VirtualizationMode to Recycling than basic default virtualization. See http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.aspx
Related
I have a MapControl which is supposed to be filled with multiple objects (500+). These objects represent some kind of POI. When the user taps on the object (pushpin) I display more info about the POI. So, I need:
A MapControl capable of handling high amount of child objects
Intercept Tappedevent of the child object
In order to achieve the second goal I decided to define my own pushpin template:
<maps:MapControl x:Name="Map">
<maps:MapItemsControl ItemsSource="{Binding Pushpins}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<Image Width="40"
Height="40"
Source="{ ... }"
Tapped="OnPushpinTappedAsync"
maps:MapControl.Location="{Binding Location}"
maps:MapControl.NormalizedAnchorPoint="{Binding AnchorPoint}" />
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:MapControl>
This works great except for the fact that.. the visual out of such approach is AWFULL. Every time I move a map, every Pushpin flickers a lot. It's like they are not, I don't know, bound to the position. They are also lagging. It looks really bad. Rendering of those objects is really poor.
The alternative is to add elements to the MapControl's MapElements property. It makes rendering of those objects really nice.
But then I loose binding ability and will have to workaround it - I'm not a big fan of that. There's also a second problem - from what I've read, rendering objects of the MapElements collection is a best effort deal. So it does not guarantee that it will succeed. And that is not an option for me, as in the future I plan to add clustering functionality, so I need to have a full control over what is being rendered on the map and what is not.
Do you have any idea why these MapControl's elements flickers so much? What can I do to prevent it? Thanks in advance for any hint or answer.
I'm facing the exact same problem. Seems to me, that the MapControl is completely broken. There are many more bugs besides performance :(
You cannot really solve the problem, but you can create a "oldschool" WP8.0 Silverlight application and use something like this:
<Page xmlns:map="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps">
<map:Map Grid.Row="1" x:Name="myMap">
<tool:MapExtensions.Children>
<tool:MapItemsControl>
... and so on ...
This performs great but of course you have to change everything from Win(P)RT to Silverlight...
I too faced this problem, but I find this library to be usefull.
Hopefully Microsoft updates the MapControl for Windows 10.
Try this:
Tag="{Binding index_of_collection}"
and this:
OnPushpinTappedAsync()
int index = (int)(sender as Image).Tag; //index_of_collection
I have something like
<ScrollView>
<StackPanel Orientation="Vertical">
<TextBox>
<TextBox>
*** // Tons of TextBoxes
<TextBox>
<RadJumpList> // Just a ListBox from Telerik
</ScrollView>
For now, the whole page is scrollable (due to ScrollViewer) and RadJumpList is also scrollable itself (by definition). How to disable RadJumpList from scrolling?
PS: probably, too many "scroll"s per a question, but i guess its pretty intuitive :)
EDIT: from my experience, this is bad idea. If list has 100+ items, it can delay page loading for a several seconds list would be loaded whole at once. Better idea is to put all TextBoxes to the ListBox via dataTemplateSelector.
If you don't set the height of your RadJumpList and disable scrolling like ScrollViewer.VerticalScrollBarVisibility="Disabled".It will be ok.
Actually, even better way is to push all stuff into the list via ItemTemplateSelector.
Otherwise, if there would be 100+ items, page would load for a several seconds.
In WPF, I can add whatever UI into ListBoxItems by providing the ListBox with an ItemTemplate:
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Gray" CornerRadius="8" Padding="4,0,4,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<CheckBox Grid.Column="1" Content="Is Active Customer" IsChecked="{Binding IsActive}"/>
<Label Content="Id:" Grid.Row="1" HorizontalAlignment="Right"/>
<Label Content="Name:" Grid.Row="2" HorizontalAlignment="Right"/>
<TextBox Text="{Binding Id}" Grid.Row="1" Grid.Column="1"/>
<TextBox Text="{Binding Name}" Grid.Row="2" Grid.Column="1"/>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Results in:
Is there any way to achieve the same in Windows Forms?
Edit:
1 - Is there any way to achieve the same in Windows Forms, all while maintaining separation of concerns between the View and the Application Logic in such a way that if I later wanted to completely redefine the View, I wouldn't have to refactor the entire application?
2 - Does winforms support databinding in such a way that each of my ListBoxItems can be bound to a complex Entity, eventually including an intermediate type conversion from Model data to UI data and back, in such a way that I don't have to write tons of boilerplate code to populate the view and then pass the UI values back into the Model in order to save?
3 - What if I wanted to introduce Animations in such a way that the currently SelectedItem would animatedly expand itself into some kind of "Row Details" mode, where you can see a lot of additional information?
4 - Does winforms support UI Virtualization in such a way that if I have, say 1 million items it doesn't take a lifetime to load the UI, and only render what's visible on screen?
5 - Say I wanted to introduce complex graphics to the equation. Is winforms rendering hardware-accelerated?
6 - How do I make all this Resolution Independent in such a way that the ListBox and all its contents stretch to the available window size in order to leverage larger screens while maintaining compatibility with smaller ones?
7 - It's been suggested to use the ListView control instead of a regular ListBox, does the ListView provide the ability to add ANY UI into it? can I add Videos for example for each item? or a complex Master/Detail template with Save and edit Buttons?
8 - Does winforms provide a consistent and adequate Document Model that enables the creation of high-fidelity WYSIWYG documents and other types of rich content?
To answer the overarching question - how to do this in WinForms - I'd suggest the following:
Use a WPF ListBox in your WinForms application, wrapped in an ElementHost. This has its own issues, but I think it's the cleanest way to get the desired effect.
if that doesn't fit the bill, then
Use a third party control suite that has components which support this (Infragistics and DevExpress both do).
Spin your own derived ListBox control that overrides paint, etc to render the desired content.
To your individual questions:
Is there any way to achieve the same in Windows Forms, all while maintaining separation of concerns between the View and the Application Logic in such a way that if I later wanted to completely redefine the View, I wouldn't have to refactor the entire application?
In the past, I've used the MVP (model-view-presenter) paradigm with Windows Forms. It works for separating the view from the business logic, albeit not as cleanly as an MVVM approach with WPF. The best advice I can give is: don't put business logic in event handlers.
Does winforms support databinding in such a way that each of my ListBoxItems can be bound to a complex Entity, eventually including an intermediate type conversion from Model data to UI data and back, in such a way that I don't have to write tons of boilerplate code to populate the view and then pass the UI values back into the Model in order to save?
No. Windows Forms databinding does not support complex data binding. You could implement something yourself via ICustomTypeDescriptor or IBindingSource that can take complex paths and evaluate them for binding purposes...but nothing exists out of the box for this.
What if I wanted to introduce Animations in such a way that the currently SelectedItem would animatedly expand itself into some kind of "Row Details" mode, where you can see a lot of additional information?
You'd have to roll your own Windows Forms ListBox and ListBoxItems and override the paint operations.
Does winforms support UI Virtualization in such a way that if I have, say 1 million items it doesn't take a lifetime to load the UI, and only render what's visible on screen?
Not out of the box, but some third party control suites have components that support types of virtualization...but not at all in the same way WPF does.
Say I wanted to introduce complex graphics to the equation. Is winforms rendering hardware-accelerated?
Windows Forms is based on GDI+. GDI+ is not hardware accelerated: Windows Forms very slow under Windows7?
How do I make all this Resolution Independent in such a way that the ListBox and all its contents stretch to the available window size in order to leverage larger screens while maintaining compatibility with smaller ones?
You can use Docking and Anchoring in Windows Forms to accomplish this. Or you can add custom event handlers to perform appropriate layout adjustments based on resolution and Window size.
It's been suggested to use the ListView control instead of a regular ListBox, does the ListView provide the ability to add ANY UI into it? can I add Videos for example for each item? or a complex Master/Detail template with Save and edit Buttons?
This is simplifying...but a ListView is simply a ListBox that supports multiple view types. It is also more limited in terms of databinding. http://blog.gfader.com/2008/09/winforms-listbox-vs-listview.html.
Does winforms provide a consistent and adequate [Document Model][2] that enables the creation of high-fidelity WYSIWYG documents and other types of rich content?
No. Not at all. Not even a little bit.
In short, if it's an acceptable solution, I'd wrap your WPF ListView in an ElementHost and call it a day.
We did this by using UserControls in a scrollable panel.
Prepared a user control which has all the editing control on it.
Add them to a scrollable panel with dosk property is set to Top.
Implemented the item selection behaviour by watching the focus and click events on the added user control items.
I have a strange behaviour with VirtualizingStackPanel. I have a list with items that contains TextBlock with TextWrap="Wrap". Here is the code:
<ListBox x:Name="messagesList" ItemsSource="{Binding Messages}" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
...
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<CheckBox Style="{Binding Own, Converter={StaticResource MsgTypeToStyle}}"
Tag="{Binding TimeString}"
IsEnabled="True">
<TextBlock Text="{Binding Content}" TextWrapping="Wrap"/>
</CheckBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
It works pretty good, but if I try to scroll very fast (using mouse on emulator, not prommatically) there is some lagging in scroll, probably HorizontallOffset sometimes calculates wrong, and in the bottom in ends with very strange result (see image, right image demostrates normal behaviour).
After research I figured out that problem in combination VirtualizingStackPanel and TextBlock.TextWrap="Wrap", if I remove one element from this couple all works correctly.
But I need virtualization because of big items count, and TextWrap for correct text displaying.
So I think about making my own implementation of Virtualizing Panel, can you please guide me, how to do this, or how to fix current problem?
UPD: The problem:
on the first two images ListBox is already(!) scrolled to the bottom (it can't be scrolled down any more), but elements placed incorrectly, correct placing shown on the right image. This happens only if you will scroll very fast.
UPD2: Thanks to Milan Aggarwal. He provided a good case of my problem here. Seems that is really a bug in ListBox. Workaround, provided doesn't fit in my scenario, because I need to interact with controls inside ListBox item.
Now I'm trying to catch ManipulationCompleted event and check if it is Inertial, if so that means scroll and I set focus to page:
void messagesList_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
if (e.IsInertial)
this.Focus();
}
P.S. thanks for good luck wishes;)
Inorder to overcome the black occurrence on scrolling you need to virtualize your scroll control. For that you should inherit IList and create a Collection of your own similar to ObservableCollection in which you will have to override the default indexer depending on your caching requirement and simultaneously maintain a cache for your items. I feel this might be what you are looking for: http://blogs.msdn.com/b/ptorr/archive/2010/08/16/virtualizing-data-in-windows-phone-7-silverlight-applications.aspx
There is a sample project on that page. Try that out.
I also feel that you are facing this problem http://blog.rsuter.com/?p=258. I guess this will be solved using virtualization itself. Hope it helps
What is the problem on 2nd screen? You mean large empty space after last message? Last message not being put at the bottom of page? Am I getting this right?
Actually i didn't try to reproduce your code and bug but my point is that since you are using 3rd party libs (Silverlight Toolkit) in your app, why not to use Coding4Fun Tools as well?
I wrote this dummy class:
public class Message
{
public string Time { get; private set; }
public string Content { get; private set; }
public Message(string time, string content)
{
Time = time;
Content = content;
}
}
Then i put this dummy code in main page constructor:
var _messages = new ObservableCollection<Message>();
for (int i = 0; i < 50; i++)
{
_messages.Add(new Message("12:40", "Teh very long string which should be wrapped. Pavel Durov gives WP7 Contest winners less money than he did for Android/iOS winners. FFFUUUUUUUUUUUUUU "));
}
this.ListBox.ItemsSource = _messages;
And in xaml i put a listbox with chat bubble control of toolkit:
<ListBox x:Name="ListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<c4fToolkit:ChatBubble>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="{Binding Content}"
TextWrapping="Wrap"/>
<TextBlock Grid.Row="1"
Text="{Binding Time}"
HorizontalAlignment="Right"/>
</Grid>
</c4fToolkit:ChatBubble>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I ran it and saw no strange behaviours, maybe little bit of lagging.
There is the result:
Hope i did some help.
Удачи с конкурсом, я б сам поучаствовал, но не верю, что за 1,5 месяца удастся сделать приличный клиент.
What is the problem at the second image? Is it that the BlackArea showed up at all, or is it that the ScrollView did not "bounceback" after the scrolling ended to fill the black area with content?
It is crucial to know this, because ... this effect is simply natural to WPF/WP7..
BTW. the scroller should "bounceback" after the over-scrolling, but it seems it has a bug and sometimes forgets to do it.
I'm asking because black/white areas are quite often not only on WP7, but and anywhere where there's a XAMLish ScrollViewer with inertial scrolling. You see, when scrolling faster than the platform can provide new items, you just scroll outside of the pre-calculated items and once you "over"scroll very far, the slowly-incoming items abruptly discover that there are no more items, hence - back empty area..
This happens mostly when some conditions happen at once: you scroll fast (yay), your bindings are slow (overly complicated expressions), your template-rendering is slow (complex non-reusable UI templates), the bindings does not know how many items there are (bound to IEnumerable not IList -> no .Count information!), or the renderer doesnt know how much height to reserve for an item (the item is not constant-height, but eveyr item has to be calculated to determine its own exact height).
If you want to correct it, you must fight with those causes first or you must implement your own Scrolling or hack into virtualizing stack panel and synchronize the feeding of items from bindingsource with the scrolling to let the scroller guess the total height better: for example, display only a small items at once, listen to scrolling events and add/remove next pack of items from head/tail of the list dynamically.. This will solve the problem by not allowing to scroll fast :)))))
I believe that constraining the item height is the easiest way. Can't you do something smart to make the items actually constant-sized?
I suggest you create the simplest possible function that computes a height for the wrapped textblock and bind to that. This way, you get the benefit of variable height items in the listbox, but get to keep using the virtualizing stack panel.
I'm having a problem with the autocompletebox from the toolkit for windows phone. I bind it to some data, then when i press it and start typing, it discovers some items but they are displayed wrong (the list is shown separated from the box, and also if i click on any item, nothing happens. If i click where the item would be supposed to be (for example, right on the top of the box), then it gets selected. It looks like a rendering problem (bug?)) but perhaps i'm doing something wrong. Here's the code for the box :
<DataTemplate x:Key="DataTemplate1">
<ContentControl Content="{Binding Name}" Margin="8,7"/>
</DataTemplate>
<toolkit:AutoCompleteBox ItemsSource="{Binding}" x:Name="txtSelectValues" MinWidth="250" Margin="0,0,0,0" ItemTemplate="{StaticResource DataTemplate1}" VerticalAlignment="Top" />
Found it. It's a bug with the AutoCompleteBox. When inside a scrollviewer control, the dropdown gets messed up and displayed in an incorrect position
Its not just that is also to do with being placed inside of a Pivot/Panaroma as well as the scrollviewer, the silverlight gurus have stated they haven't a timeline for the fix for the Pivot control, and there is a nasty hack
http://silverlight.codeplex.com/workitem/7574
I think the answer might just be that you shouldn't be using a ContentControl directly used like this. Try using something like a TextBlock instead - e.g.:
<DataTemplate x:Key="DataTemplate1">
<TextBlock Text="{Binding Name}" Margin="8,7"/>
</DataTemplate>
If that's not the answer, then try pulling back to a simple example - especially removing all the Margin's, Width's, Alignment's, etc - then put them back in one-by-one to work out and understand what is causing the effect you are seeing.