WPF is rendering data very slowly - wpf

More than 8000 objects are getting binded to ListView control and a object has two properties.ie ID and Description).
LstViewTextBLocks is a Listview control whose itemsource is assigned to 'view' which is of type ICollectionView
Data gets loaded fast in codebehind(as noticed in debugging) but while rendering the data it takes almost 6 minutes and also when the data is rendered while scrolling through it becomes very laggy.
<TabItem Header="data" Background="Gray" Name="textPicker" >
<!--<local:TextPickerView/>-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label DockPanel.Dock="Left" Content="Filter:" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="TextblockFilter1" Grid.Row="0" Grid.Column="1"
Text="{Binding TextSearch,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<ScrollViewer Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2"
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<**ListView** Name="LstViewTextBLocks"
VirtualizingStackPanel.VirtualizationMode="Recycling" SelectionMode="Single"
VirtualizingPanel.IsVirtualizing="True" IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedItem,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">
<ListView.View>
<GridView>
**<GridViewColumn Header="ID" Width="Auto" DisplayMemberBinding="{Binding ID}" />
<GridViewColumn Header="Description" DisplayMemberBinding="{Binding Description}" />**
</GridView>
</ListView.View>
</**ListView**>
</ScrollViewer>
</Grid>
</TabItem>
ItemsSource of my listview in the code behind was set like this:
this.LstViewTextBLocks.ItemsSource = this.View;

Remove the ScrollViewer from your code. This ScrollViewer allows for the ListView to occupy all the height it needs for your 8000+ rows. This results in removing the virtualization from the ListView. ListView has its own Scrollviewer which will be triggered in, and will also help in virtualization and fast performance comparatively.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label DockPanel.Dock="Left" Content="Filter:" Grid.Column="0" Grid.Row="0"/>
<TextBox Name="TextblockFilter1" Grid.Row="0" Grid.Column="1"
Text="{Binding TextSearch,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<ListView Name="LstViewTextBLocks"
Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2"
VirtualizingStackPanel.VirtualizationMode="Recycling" SelectionMode="Single"
VirtualizingPanel.IsVirtualizing="True" IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedItem,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" Width="Auto" DisplayMemberBinding="{Binding ID}" />
<GridViewColumn Header="Description" DisplayMemberBinding="{Binding Description}" />
</GridView>
</ListView.View>
</ListView>
</Grid>

Related

Color Change in WPF MVVM

I am completely new to wpf and MVVM. I have created a code which binds the values from the listView to the Textbox and Viceversa.
The data to the list view is sent from the database.
Now I would like to change the color of the row in the list view when text in the textbox is updated.
I also have similar connection of two checkboxes with the same listview. Could you please help since I could not find a correct solution for the same.
Below is my code:
<UserControl>
<Grid HorizontalAlignment="Center" Margin="20,20,20,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="236"></ColumnDefinition>
<ColumnDefinition Width="Auto" MinWidth="494"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Mitarbeiter Status" Margin="0,0,0,10"/>
<TextBox Grid.Row="0" Grid.Column="1" Width="261" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Text="{Binding ElementName=EmployeeStatusListView, Path=SelectedItem.Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }"/>
<CheckBox Grid.Row="1" Grid.Column="0" Content="IsAdmin" Margin="0,10,0,10" IsChecked="{Binding ElementName =EmployeeStatusListView, Path=SelectedItem.IsAdmin,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True }"/>
<CheckBox Grid.Row="1" Grid.Column="1" Content="IsMandatory" Margin="0,10,0,10" IsChecked="{Binding ElementName =EmployeeStatusListView, Path=SelectedItem.IsMandatory,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True}"/>
<StackPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" Margin="0,10,0,10" >
<Button Width="100" Content="Hinzufugen" Command="{Binding Path=AddCommand}" CommandParameter="{Binding ElementName=EmployeeStatusListView ,Path=SelectedItem}" Margin="100,10,30,0"/>
<Button Width="90" Content="Update" Command="{Binding Path=UpdateCommand}" CommandParameter="{Binding ElementName=EmployeeStatusListView, Path=SelectedItem}" Height="30" Margin="20,10,30,0" />
<Button Width="90" Content="Löschen" Command="{Binding Path=DeleteCommand}" CommandParameter="{Binding ElementName=EmployeeStatusListView, Path=SelectedItem}" Height="30" Margin="20,10,30,0" />
</StackPanel>
<ListView SelectedItem="EmployeeStatusSelect" SelectedIndex="0" Grid.Row="3" Grid.ColumnSpan="2" Name="EmployeeStatusListView" ItemsSource="{Binding EmployeeStatusList}" RenderTransformOrigin="0.502,0.66" Margin="0,20,0,-19" >
<ListView.View>
<GridView>
<GridViewColumn Header="ID" Width="120" DisplayMemberBinding="{Binding Id, Mode=TwoWay}"/>
<GridViewColumn Header="Mitarbeiter Admin Nummer " Width="200" DisplayMemberBinding="{Binding IsAdmin}"/>
<GridViewColumn Header="Mitarbeiter Status " Width="200" DisplayMemberBinding="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<GridViewColumn Header="Mandantory " Width="200" DisplayMemberBinding="{Binding IsMandatory, Mode=TwoWay}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>

WPF SelectedItem working inconsistently....(MVVM data binding)

I have a WPF ListBox that is a child of a ListView.
The ListBox has a 'SelectedItem' attribute that is bound to a property on my ViewModel SelectedTask.
When I click a row on my ListBox, then it updates SelectedTask. But only sometimes.....
By sometimes:
Every List Box row will update SelectedTask at least once
The ones in the "middle" of the screen will always update SelectedTask. I can hop from one row to another and back again, each time SelectedTask is updated
The ones at the top or bottom of the screen will update SelectedTask, but maybe only once. If I select another row and then return to this one, I can not get SelectedTask to be updated.
A highly cut-down/edited view of my XAML is as follows:
<ListView ItemsSource="{Binding WorkItems}" >
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="850"/>
</Grid.ColumnDefinitions>
/* Display properties from Work Item */
<TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Code}" />
/* This SelectedItem works sometimes, but not all the time */
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Tasks}" SelectedItem="{Binding Path=DataContext.SelectedTask, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,5">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
/* Display properties from Work Item Task */
<TextBlock Text="{Binding Path=Description}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
EDIT
I was asked what the SelectedTask property looked like:
public MyTaskType SelectedTask
{
get { return _selectedTask; }
set
{
_selectedTask = value;
NotifyPropertyChanged();
}
}

wpf gridsplitter issues -- both sides shrink

Gridsplitter trouble:
I have a: grid with 4 columns
Column 0 contains a grid with 3 columns
Column 1 contains a gridsplitter
Column 2 contains a stackpanel of width 20 pixels
Column 3 contains a grid with 3 columns
When the gridsplitter is moved to either the left or right, BOTH panels shrink the same amount -- one should shrink and the other should grow.
I am hesitant to include the xaml, but you are going to ask for it, so here is an abridged version. I have only removed a few unrelated controls, and gutted the treeviews and listviews. If you really need the whole thing, then of course I can supply it.
Thanks for any help!
<Window x:Class="Calvin.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="Calvin" >
<DockPanel Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" LastChildFill="True" >
<Grid DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RenderTransformOrigin="0.5,0.497" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" TextWrapping="NoWrap" Text="Field One" HorizontalAlignment="Stretch"/>
<TextBox Grid.Row="0" Grid.Column="4" Grid.ColumnSpan="3" TextWrapping="NoWrap" Text="Field Two" HorizontalAlignment="Stretch" />
<TreeView DockPanel.Dock="Left" Grid.Column="0" Grid.Row="1" Name="PaneOneTree"
Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
</TreeView>
<GridSplitter Grid.Column="1" Grid.Row="1" Width="5" HorizontalAlignment="Center"/>
<ScrollViewer Grid.Column="2" Grid.Row="1" >
<ListView DockPanel.Dock="Left" Name="FileDetailsLeft" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" >
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" />
<GridViewColumn Header="Size" Width="120" />
<GridViewColumn Header="Access Time" Width="120" />
<GridViewColumn Header="Extension" Width="120" />
</GridView>
</ListView.View>
</ListView>
</ScrollViewer>
</Grid>
<GridSplitter Grid.Column="1" Grid.Row="0" Width="5" HorizontalAlignment="Left" />
<StackPanel Grid.Column="2" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Center" Width="Auto" Background="Red">
<Button >Move</Button>
<Button >Other</Button>
</StackPanel>
<Grid Grid.Column="3" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" TextWrapping="NoWrap" Background="Cornsilk"
Text="Pane Two Text" HorizontalAlignment="Stretch"/>
<TextBox Grid.Row="0" Grid.Column="4" Grid.ColumnSpan="3" TextWrapping="NoWrap"
Text="Pane Two Text" HorizontalAlignment="Stretch" Background="Linen" />
<TreeView DockPanel.Dock="Left" Grid.Column="0" Grid.Row="1" Name="PaneTwoTree" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Background="SeaShell" >
</TreeView>
<GridSplitter Grid.Column="1" Grid.Row="1" Width="5" HorizontalAlignment="Center" />
<ScrollViewer Grid.Column="2" Grid.Row="1" >
<ListView DockPanel.Dock="Left" Name="FileDetailsRight"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Background="Moccasin" >
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" />
<GridViewColumn Header="Size" Width="120" />
<GridViewColumn Header="Access Time" Width="120" />
<GridViewColumn Header="Extension" Width="120" />
</GridView>
</ListView.View>
<ListViewItem >List Item</ListViewItem>
<ListViewItem >List Item</ListViewItem>
<ListViewItem >List Item</ListViewItem>
<ListViewItem >List Item</ListViewItem>
<ListViewItem >List Item</ListViewItem>
<ListViewItem >List Item</ListViewItem>
<ListViewItem >List Item</ListViewItem>
</ListView>
</ScrollViewer>
</Grid>
</Grid>
</DockPanel>
</Window>
And, of course, feel free to suggest better ways to do anything:) -- I'm still learning.
:bp:
I had the same issue. When I moved one GridSplitter it would also move the other (Usually in the opposite direction.). I eventually discovered that I had forgotten to set a property of the GridSplitter. For a GridSplitter you MUST have both vertical and horizontal properties set ie...
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" Width="2"
VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
</Grid>
Ok, I see your problem now... basically, you can't set an exact Width on a column who's Width will be changed by a GridSplitter control. Instead, you can only set MinWidth and/or MaxWidth property on the ColumnDefinition, but be aware that you can then not use the "*" notation. Also, looking at the code example below, you can see that you could have stripped out a whole load more code for your question example... this was all that was required to demonstrate your problem (before I fixed it):
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="150" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" MinWidth="150" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Grid.Column="0" Fill="PowderBlue" />
<GridSplitter Grid.Column="1" Background="Black" HorizontalAlignment="Stretch" />
<Rectangle Grid.Column="2" Fill="Red" Height="100" />
<Rectangle Grid.Column="3" Fill="Purple" />
</Grid>

How to resize Listview and TreeView with window resize wpf

I have a grid with these column and row definitions
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
MinWidth="154" />
<ColumnDefinition Width="Auto"
MinWidth="175" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
Inside the grid I have a Listview and it has a(gridview).
<ListView Grid.Column="0"
Grid.Row="2"
Name="ListView"
ItemsSource=" {Binding MessageFields}"
Margin="10,12,0,-5"
Grid.ColumnSpan="3">
<ListView.View>
<GridView>
<GridViewColumn Width="100">
<GridViewColumnHeader Content="{StaticResource IdColumnContent}" />
</GridViewColumn>
<GridViewColumn Width="100">
<GridViewColumnHeader Content="{StaticResource CodeColumnContent}" />
</GridViewColumn>
<GridViewColumn Width="Auto">
<GridViewColumnHeader Content="{StaticResource NameColumnContent}" />
</GridViewColumn>
<GridViewColumn Width="100">
<GridViewColumnHeader Content="{StaticResource PositionColumnContent}" />
</GridViewColumn>
<GridViewColumn Width="100">
<GridViewColumnHeader Content="{StaticResource MappedListColumnContent}" />
</GridViewColumn>
<GridViewColumn>
<GridViewColumnHeader Content="{StaticResource MappingRuleColumnContent}" />
</GridViewColumn>
</GridView>
</ListView.View>
Inside the grid I also have a TreeView
<TreeView
Grid.Column="3" Grid.Row="2" ItemsSource="{Binding , Mode=TwoWay}">
When I maximize my window my treeview stays at its place but according to window resize.
But my Listview it expands with the window but my last column stretches with the window and when I reduce/restore down the window size it shrinks .
how can I make the grid and the tree to stretch appropriately on window resize?
Basically, the last "column" in your GridView is filling the remaining space in your window? And it is not actually a column, but just empty space?
If that is the case, you should check out the answer for
WPF : Extend last column of ListView's GridView
I would personally ditch the ListView/GridView, however, and use the DataGrid (if you are using .net 4 or greater).

Data grid height is too tall when using word-wrap in text block column

I desire to make data grid with one column representing rather lengthy text values. So my goal functionality is:
Column width to be as wide as remaining window space (window can be re-sized)
Word-wrap text as necessary
Limit data grid height to remaining height of window and provide vertical scroll as necessary
The following code meets the first two items and provides a functioning vertical scroll bar, but the data grid height is bizarrely too tall for the content it is showing. Removing word-wrap from the text block fixes this... but I need the word-wrap.
How can I keep the word-wrap functionality without the data grid height getting too excessive?
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- other controls in different parts of the data grid -->
<DataGrid Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left"
Margin="0,6,6,6" Name="dgMessages" VerticalAlignment="Top"
Background="DarkGray" HeadersVisibility="None"
AlternatingRowBackground="Gainsboro" CanUserResizeColumns="False"
CanUserResizeRows="False" CanUserSortColumns="False"
AutoGenerateColumns="false" BorderBrush="Black" HorizontalGridLinesBrush="{x:Null}"
ItemsSource="{Binding Messages, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<DataGrid.Columns>
<dg:DataGridTemplateColumn Width="*">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}"
TextWrapping="WrapWithOverflow"
Padding="5,5,5,5" />
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</ScrollViewer>
"dg" namespace is "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Removing the scrollviewer and setting the height of the row containing the data grid to "*" fixed this. Wrapping text in the data grid column is treated normally when the data grid is not in a row that is automatically sized to content.
Here is the end code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- other controls in different parts of the data grid -->
<DataGrid Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left"
Margin="0,6,6,6" Name="dgMessages" VerticalAlignment="Top"
Background="DarkGray" HeadersVisibility="None"
AlternatingRowBackground="Gainsboro" CanUserResizeColumns="False"
CanUserResizeRows="False" CanUserSortColumns="False"
AutoGenerateColumns="false" BorderBrush="Black" HorizontalGridLinesBrush="{x:Null}"
ItemsSource="{Binding Messages, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<DataGrid.Columns>
<dg:DataGridTemplateColumn Width="*">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}" TextWrapping="WrapWithOverflow" Padding="5,5,5,5" />
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>

Resources