Limit the number of rows in a ListView / GridView - wpf

I have a ListView with a GridView used as the View, similar to the example here:
<Grid>
<ListView Margin="10" Name="lvUsers" ItemsSource="{Binding UsersView}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
How do I go about limiting the maximum number of rows displayed?
I've seen other examples refer to GridView.ItemsPanel (see below), but this simply does not work for me ("ItemsPanel not found in GridView").
Is my only solution to maintain the underlying CollectionView?
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid MaximumRowsOrColumns="5"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>

Is my only solution to maintain the underlying CollectionView?
Yes. The control itself has no way of limiting the number of items.
You should control this yourself by not adding too many items to the source collection (UsersView in this case).
There is no way to limit the maximum number of items in XAML.

You could just filter your UsersView and use the Take method to get the number of items you want to show.
UsersView.Take(5);
Unless you need the whole UsersView in other places.

Related

which wpf control should I use in case i need only 2 columns?

which wpf control Should i use in case I need only two columns. the first colum contains Property name and second column contains its value. however, on the top of all those properties I need a header of each columns like PROPERTY and VALUE. I know datagrid would not be a good solution for this. can someone suggest me which control to use or should I stick to Grid and set those header manually.
If you really can't use a DataGrid, then the GridView is probably your best bet... and when I say best, I mean easiest really. Assuming that you have a collection of your data type named Items and that the data type inside the collection has two properties, Property and Value, you could use this:
<ListView ItemsSource="{Binding Items}" HorizontalAlignment="Center"
VerticalAlignment="Center">
<ListView.View>
<GridView>
<GridViewColumn Header="Property" DisplayMemberBinding="{Binding Property}" />
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}"/>
</GridView>
</ListView.View>
</ListView>

How to show properties of a list in a list in a listview?

I am implementing an application in wpf , MVVM pattern.
I want to implement a listview with objects. These objects contains a list. On default this list contains only 1 object. But in the listview, I want to show that certain object. So the properties of the object in the list. This is my first problem.
But I also have to be able to have more objects in this list. My second problem is that i don't really know how to realise this? And i also have to show the properties of these objects in the listview.
Maybe a treeview? but i don't get how that i got to begin on this..
Someone with some ideas?
You can arbitrarily nest DataTemplates, e.g.
<ListView ItemsSource="{Binding Data}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
<!-- Internal Manchines list gets its own ListView -->
<GridViewColumn Header="Machines">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ListView ItemsSource="{Binding Machines}">
<ListView.View>
<GridView>
<GridViewColumn Header="Model" DisplayMemberBinding="{Binding Model}"/>
<GridViewColumn Header="Manufacturer" DisplayMemberBinding="{Binding Manufacturer}"/>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Occupation" DisplayMemberBinding="{Binding Occupation}"/>
<GridViewColumn Header="Status" DisplayMemberBinding="{Binding Status}"/>
</GridView>
</ListView.View>
</ListView>
This can be improved in terms of alignment, e.g. you could set up a Grid in the DataTemplate with a shared size column to make all lists the same width (making the internal columns align might be a bit hard though)
Further you could define a style to collapse empty lists (which otherwise would show the header without items).

How to evenly space out GridViewColumns in GridView?

This is my XAML:
<ListView ItemsSource="{Binding Items}">
<ListView.View>
<GridView>
<GridViewColumn Header="Property1" DisplayMemberBinding="{Binding Property1}" />
<GridViewColumn Header="Property2" DisplayMemberBinding="{Binding Property2}" />
</GridView>
</ListView.View>
</ListView>
I want these 2 columns to take up the width of ListView in 1:1 ratio.
How can I achieve this?
Edit: I found this suggestion on MS Connect. This would perfectly solve my problem.
However it is closed as postponed (for 2.5 years now..)
What comes to mind is using internal Grids in the templates which each have a ColumnDefinition with the same SharedSizeGroup, the GridView should then have Grid.IsSharedSizeScope="True" and the columns of the grid view should themselves be unresizable (if that is possible), cannot test that right now so it's a bit sketchy.
Another method would be to bind both Widths of the GridViewColumns to the width of the ListView and then use a custom converter to get an appropriate fraction of that back.

Multicolumn listview in WPF at design time

I might sound dumb here, but I want to do something really simple. At design time, I want to add columns to a listview control and add some data to it. I need to add combobox in each column of the listview. The thing I am not able to find is where to mention the column number in the listviewitem. Any help appreciated guys.
<ListView IsSynchronizedWithCurrentItem="True" Margin="8,68,304,188"
BorderThickness="2,2,2,2">
<ListView.View>
<GridView>
<GridViewColumn Width="150" Header="Column1"/>
<GridViewColumn Width="150" Header="Column2"/>
</GridView>
</ListView.View>
<ListViewItem>
</ListViewItem>
</ListView>
Each column in the listviewitem is rendered based on the GridView definition, so there is no real concept of column numbers. What you do is bind objects to the the listview's itemsource and it creates listviewitems from it. Thus, there are a few hoops to jump through.
This link has an example of how to do some simple object data binding. The advantage of this is what binding structure you have for design time can probably be reused for run-time if you set the datacontext/itemsource to an empty object instead of the static one in XAML.
If you're doing this to show examples or you just have a static data source that you want to use, I would recommend using the XmlDataProvider. Then you'd change your ListView to be like this,
<ListView IsSynchronizedWithCurrentItem="True" Margin="8,68,304,188"
BorderThickness="2,2,2,2">
<ListView.View>
<GridView>
<GridViewColumn Width="150" Header="Column1" DisplayMemberPath="{Binding XPath=/A/B}"/>
<GridViewColumn Width="150" Header="Column2" DisplayMemberPath="{Binding XPath=/A/C"/>
</GridView>
</ListView.View>
<ListViewItem>
</ListViewItem>
</ListView>

WPF ListView Very Slow Performance - Why? (ElementHost, or Other Reason?)

I have a Windows Forms app, that has a single ElementHost containing a WPF UserControl... in my WPF, I have a VERY simple ListView:
<ListView Margin="4" ItemsSource="{Binding Notifications}">
<ListView.View>
<GridView>
<GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" />
<GridViewColumn Header="LastName" DisplayMemberBinding="{Binding LastName}" />
<GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}" />
<GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" />
<GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" />
<GridViewColumn Header="Zip" DisplayMemberBinding="{Binding Zip}" />
</GridView>
</ListView.View>
</ListView>
If my source has 10 items, the form loads in less than one second. If my source has 1000 items, it takes 7 seconds!!! My timer is ONLY taking the loading into account (not how much time it takes to get the items).
So my question is:
Is using an ElementHost a performance nightmare?
Is WPF DataBinding a performance nightmare?
Is the ListView a piece of crap? (btw, same results with the WPFToolkit's DataGrid)?
Use virtualization
<ListView ItemsSource="{BindingNames}"Name="lv">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<!--<StackPanel/>
If StackPanel was used, the memory consumed was over 2GB and dead slow.
-->
<VirtualizingStackPanel>
<!--Memory footprint is only 200 mb-->
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You may also want to check this excellent article on the Code Project:
WPF: Data Virtualization
By Paul McClean
http://www.codeproject.com/KB/WPF/WpfDataVirtualization.aspx
It show you a much better approach at minimal memory and bandwidth usage.
I had a case where the answers presented here didn't solve my problem. In my case, setting the MaxHeight property of the ListView to a value larger than the actual displayed height solved it immediately, thanks to this answer here, even if I cannot explain how and why it worked.

Resources