WPF GridViewRowPresenter turns all the content into Textblocks - c#

I'm trying to create a list with fully functional headers, but I can only seem to get either a list with functional headers and all list view items reduced to textblocks. OR a list view with all the buttons and text fully styled, but without the headers being properly linked. See the image below;
My ListView definition looks like this for both of them:
<ListView ItemsSource="{Binding ScenarioComponents}" Style="{StaticResource ListViewWithHeader}" ItemContainerStyle="{StaticResource ListViewWithHeaderItem}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto" Header="{Binding NameHeader}" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Width="Auto" Header="{Binding TypeHeader}" DisplayMemberBinding="{Binding Type}"/>
<GridViewColumn Width="Auto" Header="{Binding InfoHeader}"/>
<GridViewColumn Width="Auto" Header="{Binding ExportHeader}"/>
<GridViewColumn Width="Auto" Header="{Binding DeleteHeader}"/>
</GridView>
</ListView.View>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="1.5*"/>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding Name}" HorizontalAlignment="Left"/>
<Label Grid.Column="1" Content="{Binding Type}" Background="{StaticResource XVROrange}"/>
<Button Grid.Column="2" Style="{StaticResource BorderLessButton}" Command="{Binding MoreInfoCommand}">
<Button.Content>
<Image Source="/Views/Images/cc2_gui_information_default.png"/>
</Button.Content>
</Button>
<Button Grid.Column="3" Style="{StaticResource BorderLessButton}" Command="{Binding ExportCommand}">
<Button.Content>
<Image Source="/Views/Images/cc2_gui_export_default.png"/>
</Button.Content>
</Button>
<Button Grid.Column="4" Style="{StaticResource BorderLessButton}" Command="{Binding DeleteCommand}">
<Button.Content>
<Image Source="/Views/Images/cc2_gui_b_delete.png"/>
</Button.Content>
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And the only difference in the styling is that the one with the Headers working uses a GridViewRowPresenter in the ListViewItem like this:
<Style x:Key="ListViewWithHeaderItem" TargetType="ListViewItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" Padding="0" Background="Transparent" BorderBrush="{StaticResource XVR70}" BorderThickness="1">
<GridViewRowPresenter Content="{TemplateBinding Content}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And the second one uses the same styling only with a ContentPresenter instead of the GridViewRowPresenter without any embellishments.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Background="Transparent" BorderBrush="{StaticResource Black47}" BorderThickness="0,0,0,0">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
For some reason using the GridViewRowPresenter means every item in my ListView.ItemTemplate's DataTemplate gets turned into a Textblock. And I can't figure out why. I'd really prefer to keep using the GridViewRowPresenter though as this means the headers are bound to the items in the list and scale with them and everything.
Has anyone got any idea how I can style this to work?

Can you put your templates from the ItemTemplate into the GridViewColumns?
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Width="Auto" Header="{Binding NameHeader}" DisplayMemberBinding="{Binding Name}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Label Grid.Column="0" Content="{Binding Name}" HorizontalAlignment="Left"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!-- more columns -->
</GridView.Columns>
</GridView>
</ListView.View>

Related

Groups went missing in ListView after expanding and collapsing expander in WPF C# with IsVirtualizing set to True

I have ListView and there is Grouping going on in it for one of the field 'Name'. The ItemSource is bound to an ObservableCollection. Somehow when grouping is applied, the virtualization is turn off and because I am displaying large amount of data, I turned virtualization back on.
But I notice something strange on the group expender, once I expand and collapse a group, the groups below it will be gone missing. To illustrate this, below are the screenshots I captured,
screenshot
Here's my XAML for the ListView. When I set VirtualizingPanel.IsVirtualizing="True", the above problem is seen.
<ListView Name="ReportListView" Grid.Row="1"
ItemsSource="{Binding LalaCollection}"
AlternationCount="2"
ScrollViewer.VerticalScrollBarVisibility="Visible"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True">
<ListView.View>
<GridView>
<GridViewColumn Header="Col A" DisplayMemberBinding="{Binding FailureType}" Width="Auto"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="Auto"/>
<GridViewColumn Header="Col B" DisplayMemberBinding="{Binding NodeName}" Width="Auto"/>
<GridViewColumn Header="Col C" DisplayMemberBinding="{Binding DeviceName}" Width="Auto"/>
<GridViewColumn Header="Col D" DisplayMemberBinding="{Binding DateTime}" Width="Auto"/>
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="False">
<Expander.Header>
< StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" VerticalAlignment="Bottom" Background="{StaticResource BackgroundColor}" Foreground="{StaticResource ForegroundColor}"/>
<TextBlock Text="{Binding ItemCount}" Foreground="Silver" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" item(s)" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
Not sure if this is a limitation for ListView Virtuaization when grouping is enabled, I am also thinking of other way to present this ObservableCollection to user with grouping in it.

How do I add a Header row in WPF in a ListView of Grid with ColumnDefintions?

I am using a ViewModel to bind the data to the view in every textblock. I shortened the code to the most important parts.
Now, I wanna add a Header row into this structure. So every Column defined below in Grid.RowDefinitions shoudl have a constant header text. Any idea how I can realise this?
<Grid>
<ListView DockPanel.Dock="Top" Margin="10" ItemsSource="{Binding CurrentView}">
<ListView.ItemTemplate>
<DataTemplate DataType="viewModel:ViewModel">
<Border BorderBrush="Black" BorderThickness="1" Margin="1">
<Expander ToolTip="Expand" ExpandDirection="Down" Foreground="Black">
<Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Width="20" Text="{Binding Model.Number, StringFormat='#{0}', Mode=OneWay}" TextAlignment="Left" Margin="5" />
<Image Grid.Column="1" />
<TextBlock Grid.Column="2" TextAlignment="Center" Margin="5" Width="50">
<Hyperlink />
</TextBlock>
<TextBlock Grid.Column="3" TextAlignment="Left" Margin="5" TextWrapping="Wrap" />
<TextBlock Grid.Column="4" TextAlignment="Center" Margin="5" Width="100" />
<Button Grid.Column="5" />
</Grid>
</Expander.Header>
<GroupBox Header="Description" FontWeight="Bold">
<TextBlock Text="{Binding Model.Description, Mode=OneWay}" TextWrapping="Wrap" FontWeight="Normal" TextAlignment="Left" Margin="5" />
</GroupBox>
</Expander>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
OK, you guys are a good help :) i changed the structure to the code below and the headers are working fine!
But in my original code, there is this expander. Everywhere in the row, i could click to expand the description. The expander now won't work with the new design. Any ideas?
Basically i want something like this:
<ListView Name="test2" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Items}">
<ListView.View>
<GridView>
<Expander>
<Expander ToolTip="Expand" ExpandDirection="Down" Foreground="Black">
<Expander.Header>
<GridView.Columns>
<GridViewColumn Header="Column1">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"> </TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Column2">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Test}"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</Expander.Header>
<TextBlock Text="Here goes the Description" />
<Expander>
</GridView>
</ListView.View>
</ListView>
How it should look like (please ignore my paint skills)
This would give every column a header but im not sure if this is what your intentions are:
<ListView x:Name="test" DockPanel.Dock="Top" Margin="10" ItemsSource="{Binding CurrentView}">
<ListView.ItemTemplate>
<DataTemplate DataType="viewModel:ViewModel">
<Border BorderBrush="Black" BorderThickness="1" Margin="1">
<Expander ToolTip="Expand" ExpandDirection="Down" Foreground="Black">
<Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Grid.Column="0">Column 1</Label>
<Label Grid.Column="1">Column 2</Label>
<Label Grid.Column="2">Column 3</Label>
<Label Grid.Column="3">Column 4</Label>
<TextBlock Grid.Column="0" Width="20" Text="{Binding Model.Number, StringFormat='#{0}', Mode=OneWay}" TextAlignment="Left" Margin="5" />
<Image Grid.Column="1" />
<TextBlock Grid.Column="2" TextAlignment="Center" Margin="5" Width="50">
<Hyperlink />
</TextBlock>
<TextBlock Grid.Column="3" TextAlignment="Left" Margin="5" TextWrapping="Wrap" />
<TextBlock Grid.Column="4" TextAlignment="Center" Margin="5" Width="100" />
<Button Grid.Column="5" />
</Grid>
</Expander.Header>
</Expander>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
a better structure should look more like this (example you should modify it to satisfy you own needs):
<ListView Name="test2" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Items}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Column1">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Column2">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Test}"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
I think that i now understand what you're trying to achive
I tested this solution and it works fine, please try this with your own data:
<CollectionViewSource x:Key='key' Source="{Binding Source={StaticResource MyData}}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="#Catalog" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<ListView ItemsSource='{Binding Source={StaticResource key}}' BorderThickness="0,0,0,0">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True"
BorderBrush="Gray"
BorderThickness="0,0,0,1">
<Expander.Header>
<DockPanel>
<TextBlock Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/>
<TextBlock Text="{Binding Path=Item}"/>
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="ID"
DisplayMemberBinding="{Binding ID}"
Width="100" />
<GridViewColumn Header="Titel"
DisplayMemberBinding="{Binding This}"
Width="100" />
<GridViewColumn Header="Date"
DisplayMemberBinding="{Binding Should}"
Width="100" />
<GridViewColumn Header="Something"
DisplayMemberBinding="{Binding Work}"
Width="100" />
</GridView>
</ListView.View>
</ListView>
How it looks:

Templated sub-MenuItem not fitting in parent MenuItem's container

I'm struggling with the horizontal fitting of contents when trying to display a UserControl in a ContextMenu, by templating one of its MenuItem:
<ControlTemplate x:Key="MyUserControlMenuItemTemplate" TargetType="{x:Type MenuItem}">
<Grid>
<MyUserControl/>
</Grid>
</ControlTemplate>
<MenuItem x:Key="MyUserControlMenuItem" x:Shared="False" Header="My user control">
<MenuItem Template="{StaticResource MyUserControlMenuItemTemplate}"/>
</MenuItem>
<ContextMenu x:Key="MyUserControlContextMenu" x:Shared="False">
<ContextMenu.ItemsSource>
<CompositeCollection>
<StaticResource ResourceKey="MyUserControlMenuItem"/>
<!-- More stuff here -->
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
This is mostly working, and I'm getting the context menu displayed under the desired circumstances and the UserControl accessible within it, as intended (a different question is whether this is a good design decision). The UserControl is just arranging some controls in a Grid.
The problem is that, depending on the position of the containing window and the actual screen resolution, sometimes the panel containing the templated menu item is not wide enough to hold it completely, and the user control is cut.
How could I get the UserControl to be dynamically resized in order to fit within the horizontal space available in the containing panel?
The UserControl XAML markup is as follows:
<UserControl x:Class="MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Grid.Row="0"
Height="210"
ItemsSource="{Binding ...}"
SelectedItem="{Binding ...}"
SelectionMode="Single">
<ListView.View>
<GridView ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<GridViewColumn DisplayMemberBinding="{Binding ...}" Header="First Name" Width="Auto"/>
<GridViewColumn DisplayMemberBinding="{Binding ...}" Header="Last Name" Width="Auto"/>
<GridViewColumn DisplayMemberBinding="{Binding ...}" Header="Address" Width="Auto"/>
</GridView>
</ListView.View>
</ListView>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="4"/>
<Setter Property="Height" Value="24"/>
<Setter Property="Width" Value="24"/>
</Style>
<Style x:Key="ImageStyle" TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.35"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Button x:Name="FirstPageButton" Grid.Column="0" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
<Button x:Name="PreviousPageButton" Grid.Column="1" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
<Button x:Name="NextPageButton" Grid.Column="2" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
<Button x:Name="LastPageButton" Grid.Column="3" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
<Button x:Name="OpenButton" Grid.Column="5" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
</Grid>
</Grid>
</UserControl>
I don't really think the issue is in the UserControl, though, but I may be well wrong.

Button Will Not Fire from Style

Yeah, im not sure what i have done. brain feels like swiss cheese
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Command" Value="{Binding CommandButtonClicked}"/>
<Setter Property="CommandParameter" Value="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"/>
</Style>
</Window.Resources>
Button that will Fire.
<Grid DockPanel.Dock="Top">
<TextBox BorderBrush="Transparent" BorderThickness="0" x:Name="txtInput" Padding="50,10,15,15" AcceptsReturn="True" TextChanged="txtInput_TextChanged" TextWrapping="Wrap" Foreground="Crimson" Text="{Binding UserInput, Mode=TwoWay}" Background="Transparent"/>
<Button Width="30" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,3,0,0">
<Image Source="Images/Actions list add user.ico" />
</Button>
</Grid>
Buttons that will not fire
<ListView x:Name="ListViewUsers" ItemsSource="{Binding UserNames}" DockPanel.Dock="Top" Foreground="Green" BorderBrush="Transparent">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.HeaderTemplate>
<DataTemplate>
<Button Margin="3,0,3,0" Width="30">
<Image Source="Images/Actions user group delete.ico"/>
</Button>
</DataTemplate>
</GridViewColumn.HeaderTemplate>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button>
<Image Source="Images/Actions list remove user.ico" Width="25"/>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="User ID" DisplayMemberBinding="{Binding}"/>
</GridView>
</ListView.View>
</ListView>
i have also tried adding in a separate DelegateCommand per button, but that doesnt help either. it seems to be anything that inside this ListView and is Generated at runtime after the initial render will not fire.
any ideas ?
In the "cell" DataTemplate it will have its DataContext set to the "item" within the data collection assigned to the ListView for which the "look" is being provided i.e. a "username".
But your style is using a binding that needs to access the object that contains the "CommandButtonClicked" property.
Thus you need a way to get back to the DataContext that is holding your "CommandButtonClicked" property.....so assuming you had set your "ViewModel" onto your Windows DataContext you could do this...
<ListView x:Name="ListViewUsers" ItemsSource="{Binding UserNames}" DockPanel.Dock="Top" Foreground="Green" BorderBrush="Transparent">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.HeaderTemplate>
<DataTemplate>
<Button Margin="3,0,3,0" Width="30" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DataContext}">
<Image Source="Images/Actions user group delete.ico"/>
</Button>
</DataTemplate>
</GridViewColumn.HeaderTemplate>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DataContext}">
<Image Source="Images/Actions list remove user.ico" Width="25"/>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="User ID" DisplayMemberBinding="{Binding}"/>
</GridView>
</ListView.View>
</ListView>
There are alternative ways to do what you are doing...just one suggestion...look up routed commands (you could define one and then use it in your style e.g. Command="{x:Static mynamespace::MyCommands.DoSomething}" and then set up a CommandBinding to handle them).

How to enable UI virtualization in Standard WPF ListView

I'm using .NET 4.5/VS2012, and I have a ListView looks something like this
<ListView
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
Grid.Row="1"
Name="eventLogList"
Margin="5,0,5,0"
BorderBrush="Black"
BorderThickness="2"
ItemsSource="{Binding EventLogs}"
SelectedItem="{Binding SelectedEventLog}"
local:ListViewSorter.CustomListViewSorter="EventLogViewer.UI.EventLogItemComparer"
SelectionMode="Single">
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="False">
<GroupStyle.ContainerStyle>
<Style TargetType="GroupItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock FontSize="20" TextWrapping="Wrap" Margin="0,10,0,5" >
<Bold><TextBlock Text="{Binding Name}"/></Bold> - <TextBlock FontSize="20" Text="{Binding ItemCount}"/> logs
</TextBlock>
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.View>
<GridView>
<GridViewColumn
Header="event id"
Width="120"
DisplayMemberBinding="{Binding EventID}" />
<GridViewColumn
Header="level"
Width="160"
DisplayMemberBinding="{Binding Level}" />
<GridViewColumn
Header="server"
Width="160"
DisplayMemberBinding="{Binding Server}" />
<GridViewColumn
Header="log name"
Width="160"
DisplayMemberBinding="{Binding LogName}" />
<GridViewColumn
Header="source"
Width="240"
DisplayMemberBinding="{Binding Source}" />
<GridViewColumn
Header="logged"
Width="240"
DisplayMemberBinding="{Binding Logged}" />
</GridView>
</ListView.View>
</ListView>
But still the performance is not improving at all. I found an example using ListBox, but how to virtualize a ListView? I struggled quite a bit.
I heard that with grouping, the virtualization is turned off in previous version of WPF, but with .NET 4.5, WPF has a IsVirtualizingWhenGrouping property, I already set it to True.
Update: The culprit is custom styling, after removing it, the list view runs smoothly like butter
"UI virtualization stores only visible items in memory but in a data-binding scenario stores the entire data structure in memory. In contrast, data virtualization stores only the data items that are visible on the screen in memory."
"By default, UI virtualization is enabled for the ListView and ListBox controls when their list items are bound to data."
For more info view the original MSDN source.
This article will help you a lot.Also can see..
ListView UI virtualization
WPF Data virtualizing ListView
I know this is an old question but I came across it looking for an answer to my question and wanted to share what I discovered in case it's useful for anyone else. I had a very similar situation with a ListView control that was not virtualizing. I remove the custom style that I had on it (after reading this thread and associated links) and it started virtualizing correctly.
After much investigation, comparison to the default template, and narrowing down I figure out that it was the 'CanContentScroll' property on the ScrollContentPresenter inside that template. I had not set it at all, and when I set it to true it started virtualizing properly. I also noticed that the default template had 'CanHorizontallyScroll="False"' and 'CanVerticallyScroll="False"'; those didn't seem to make a difference that I could tell in my limited testing (I'm sure someone can chime in and say what they do) but I left them in anyway.
Here is my final style (note that this was started from default and modified, so not sure where the CanContentScroll property got dropped...):
<Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}"
TargetType="ScrollViewer">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Margin="{TemplateBinding Padding}">
<ScrollViewer DockPanel.Dock="Top"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
Focusable="false">
<GridViewHeaderRowPresenter Margin="2,0,2,0"
Columns="{Binding Path=TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderContainerStyle="{Binding
Path=TemplatedParent.View.ColumnHeaderContainerStyle,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderTemplate="{Binding
Path=TemplatedParent.View.ColumnHeaderTemplate,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderTemplateSelector="{Binding
Path=TemplatedParent.View.ColumnHeaderTemplateSelector,
RelativeSource={RelativeSource TemplatedParent}}"
AllowsColumnReorder="{Binding
Path=TemplatedParent.View.AllowsColumnReorder,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderContextMenu="{Binding
Path=TemplatedParent.View.ColumnHeaderContextMenu,
RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderToolTip="{Binding
Path=TemplatedParent.View.ColumnHeaderToolTip,
RelativeSource={RelativeSource TemplatedParent}}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
<ScrollContentPresenter Name="PART_ScrollContentPresenter"
KeyboardNavigation.DirectionalNavigation="Local"
CanContentScroll="True"
CanHorizontallyScroll="False"
CanVerticallyScroll="False"/>
</DockPanel>
<ScrollBar Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{TemplateBinding HorizontalOffset}"
Style="{StaticResource StScrollBarNoMargin}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
<ScrollBar Name="PART_VerticalScrollBar"
Grid.Column="1"
Style="{StaticResource StScrollBarNoMargin}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{TemplateBinding VerticalOffset}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Categories

Resources