|
Hi
If virtualizingstackpanel provides better performance, should we then always choose virtualizingstackpanel over Grid/StackPanel then?
Under what circumstances should one choose Grid/StackPanel?
Thanks
dev
|
|
|
|
|
Actually VirtualizingStackPanel is mainly used to set the ItemsPanelTemplate for lets take an example for a ListBox where large data like 1000 or maybe 10,000 items or more have to be loaded into it.
You set it like this :
<ListBox Name="myListBox">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation = "Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
It means that you are setting the Panel for the ListBox so that "All" the items in ListBox can be arranged in a Vertical manner. Virtualization means that items will be created only when they are visible.
But if you substitute the VirtualizingStackPanel with a StackPanel , then performance will suffer heavily and your application will freeze for large amount of data.
If you think of normal circumstances like arranging two or three controls of your window like this :
<StackPanel Orientation="Horizontal">
<TextBox Text="Hello"/>
<ComboBox Name="cmbItems"/>
</StackPanel>
Then there is no point in using a VirtualizingStackPanel here as there are only 2 controls and there will be no performance enhancement at all. You can replace the StackPanel with a Grid or Canvas too.
You can also think of setting the DataTemplate for the ListBox like this :
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Item}"/>
<TextBlock Text="{Binding Path=AnotherItem}"/>
</DataTemplate>
</ListBox.ItemTemplate>
Again if you replace it with a VirtualizingStackPanel , it will not have any effect. You can as said above use Grid here too.
Its the ItemsPanelTemplate that you set matters.
So the point is for large amount of data, VirtualizingStackPanel is the correct choice and its by default used in ListBox , ListView and TreeView .
But using VirtualizingStackPanel also has some limitations. You cannot use Grouping and you have set the CanContentScroll of the ScrollViewer to True or else Virtualization will be switched off.
So it also depends on the requirement too. If you want to use Grouping, there is no point in using VirtualizingStackPanel .
Hope I was able to clear your doubt.
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
modified on Friday, April 15, 2011 3:16 AM
|
|
|
|
|
Tarun.K.S wrote: Actually VirtualizingStackPanel is mainly used to set the
ItemsPanelTemplate for lets take an example for a
ListBox <br /> where large data like 10,000 items or more have to be loaded into it.
This is a bit misleading. You do not need 10,000 items to see the benefits of VirtualizingStackPanel. Even with 200 items you will see a huge difference. If you have a ListView control with 200 items and turn OFF virtualization, your app will consume about an extra 40MB of RAM. Ask me how I know .
|
|
|
|
|
SledgeHammer01 wrote: Even with 200 items you will see a huge difference.
Really? Might not be that huge.
SledgeHammer01 wrote: Ask me how I know
Yeah I would like to know!
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
|
|
|
|
|
Are you using Visual Studio 2010? If so, may I recommend debugging the difference between the two with Mole 2010 (I've linked to it in my sig)? You'll find it very enlightening here.
|
|
|
|
|
Sorry Pete I actually use VS 2008. But I will try it for sure once I get my hands on VS 2010.
If I am not wrong, Josh Smith is its founder.
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
|
|
|
|
|
You aren't wrong. Josh is one of the founders, which is why I use it. Another reason is that one of the Visual Studio Cider team also helps to develop it - it's got that inside edge which I like.
|
|
|
|
|
Wow that's cool.
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
|
|
|
|
|
I saw 200 items add about 50MB of memory when I turned virtualization off. Thats how I know . You can turn virtualization off on the ListView. Those 200 items were nothing more then a simple TestItem with 3 CLR properties. If you've ever looked at all the parts of a ListView template (the list view itself, the scroll view, the list view item, etc), they all use a lot of visuals.
10 - 20 items realized vs. 200 items realized is a HUGE memory difference. Unless 50MB isn't considered "huge" .
|
|
|
|
|
SledgeHammer01 wrote: I saw 200 items add about 50MB of memory when I turned virtualization off. Thats how I know
Lol that was straightforward!
SledgeHammer01 wrote: 10 - 20 items realized vs. 200 items realized is a HUGE memory difference. Unless 50MB isn't considered "huge"
Heh! I don't think 50Mb is that HUGE!
But yes I got your point.
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
|
|
|
|
|
Tarun.K.S wrote:
Heh! I don't think 50Mb is that HUGE!
*Sigh*... kids today... . *One control* using an extra 50MB is "no big deal". No wonder apps are such resource hogs these days .
|
|
|
|
|
Hehhehe!
Hey why don't you also participate in the Q & A section? Just curious!
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
|
|
|
|
|
Thanks - think I get your point, unless you have very big DataGrid or List, VirtualizingStackPanel carries more overhead than a simple Grid/StackPanel.
dev
|
|
|
|
|
|
VirtualizingStackPanel is only used when you are displaying a variable number of items. Like a ListBox or a ListView, etc. You generally don't use it in your application. The differences between the various panels are too numerous to mention, you need to read up on them. The main difference is the various layout techniques and abilities.
|
|
|
|
|
|
Hi,
can any one tell me how to add the values from textbox(UI of text box) into a directive list, which is already containing a data like this...
void DerivedAttributePanel_Loaded(object sender,RoutedEventArgs e)
{
List<Directive> list = new List<Directive>();
list.Add(new Directive { DirectiveName = "Filter1", Description = "Description 1" });
list.Add(new Directive { DirectiveName = "Filter2", Description = "Description 2" });
list.Add(new Directive { DirectiveName = "Filter3", Description = "Description 3" });
lbDirectiveList.ItemsSource = list;
}
class Directive
{
public string DirectiveName { get; set; }
public string Description { get; set; }
}
basically i want to update this directive list from the user data which is enterred in the Textbox from UI of the application, so can u tell me how to do it...
|
|
|
|
|
I would recommend you to use ObservableCollection instead of List because the former can notify you whenever your collection changes.
private ObservableCollection<Directive> list;
void DerivedAttributePanel_Loaded(object sender,RoutedEventArgs e)
{
list = new ObservableCollection<Directive>();
list.Add(new Directive { DirectiveName = "Filter1", Description = "Description 1" });
list.Add(new Directive { DirectiveName = "Filter2", Description = "Description 2" });
list.Add(new Directive { DirectiveName = "Filter3", Description = "Description 3" });
lbDirectiveList.ItemsSource = list;
}
private void AddData_Click(object sender, RoutedEventArgs e)
{
Directive newDirect = new Directive { DiretiveName = txtFilter.Text, Description = txtDesc.Text };
list.Add(newDirect);
}
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
modified on Wednesday, April 13, 2011 1:41 PM
|
|
|
|
|
I have used the above code, but it is not loading(displaying) the data which i enterred in the textbox control into a listbox lbDirectiveList.
|
|
|
|
|
Are you binding to the ObservableCollection? This would typically look like this:
<ListBox ItemsSource="{Binding lbDirectiveList}" ItemTemplate="{StaticResource myDataTemplate}" />
|
|
|
|
|
No, am binding to a list...
but when am adding the values to list, it is not appearing in that listbox..
|
|
|
|
|
Are you sure that it's an ObservableCollection you are binding to? There's nothing magical about an ObservableCollection, except that for binding purposes it implements the ICollectionChanged interface and raises notifications when things have changed in it.
Check your Visual Studio output window to see if there are any binding errors in there causing it to fail.
|
|
|
|
|
You must be missing the ItemTemplate for the ListBox.
<ListBox Name=" "...>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=DirectiveName}"/>
<TextBlock Text="{Binding Path=Description}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Try now.
People with high attitude deserve the standing ovation of our highest finger!
My Blog![ ^]
|
|
|
|
|
Hello,
I have a listbox bound to a DataView showing rows from a table (ReportingUser) in a typed DataSet. The table has a DataRelation to another table (Reporting). Hence the (typed) row objects have a ReportingRow property that refers to the corresponding row in the related table.
Each row is displayed using text from the Reporting related table:
<ListBox Name="listBoxSelectedReporting" ItemsSource="{Binding User/User_ReportingUser}"
DisplayMemberPath="Row.ReportingRow.ReportingName" />
I would like to sort the listbox by ReportingName as well. I have been struggling with this for two days. None of the solutions I found via Google work. They include:
1/ Use a SortDescription. But that mechanism doesn't seem capable of following property chains, unlike DisplayMemberPath.
2/ Grab the defaultView and set the Sort property. But the mechanism is string-based and gives access to the row's columns only.
3/ Cast the defaultView to a ListCollectionView and set a custom IComparer. But the cast fails.
I also had an idea: use a partial class definition to add a new property, to be used in SortDescriptions:
partial class ReportingUserRow
{
public string ReportingName
{
get
{
return ReportingRow.ReportingName;
}
}
}
Alas when I try to use it in either DisplayMemberPath or SortDescription, I get an exception that the property doesn't exist.
UPDATE: I can use my property in DisplayMemberPath like this: DisplayMemberPath="Row.ReportingName"
Which opens the question: using the debugger I see that my listbox contains a DataView that contains DataRowView objects which in turn contain a reference to a row object (of type ReportingUserRow). How does DataRowView find out what properties are available on a ReportingUserRow ? Why does it find the columns and not my extra property ?
modified on Wednesday, April 13, 2011 6:03 AM
|
|
|
|
|
1) I'm pretty sure that doesn't work... the implementation pretty much reflects on the current type and gets a property named "x". "Row.ReportingRow.ReportingName" is not the name of a valid property.
3) Should work just fine. I do it all over the place. How are you getting the default view? Show code. If the cast is failing, what IS GetDefaultView() returning?
|
|
|
|