Wpf - Speed ListBox - c#

I've got a Wpf Application and I'm having some speed/time issues. I've got a Grid with 2 columns. The left column contains a panel with a ListBox, and when one of the items is selected it creates a new panel and sets it at the right column of the Grid. So I've got a fixed panel on the left and a changing panel on the right.
My right panel contains some details and a ListBox. When I keep changing the right panel (change selection of the left panel) it gets really slow and UI freezes. I was able to find the issue, and it was with my ListBox. It has a complex ItemTemplate and this could explain why it is slow.
My ListBox ItemTemplate:
<DataTemplate>
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="{Binding ., Converter={StaticResource MyConverter}}">
<TextBox Style="{StaticResource MyStyle}" Text="{Binding Property, Converter={StaticResource MyConverter}}" HorizontalAlignment="{Binding ., Converter={StaticResource MyConverter}}" FontSize="10" Visibility="{Binding Property, Converter={StaticResource MyConverter}}"/>
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="{Binding ., Converter={StaticResource MyConverter}}">
<Border Padding="8" CornerRadius="10,10,10,10" Background="{Binding ., Converter={StaticResource MyConverter}}">
<StackPanel Orientation="Vertical">
<TextBox Style="{StaticResource MyStyle}" Text="{Binding Property}" Visibility="{Binding ., Converter={StaticResource MyConverter}}" FontSize="14" FontWeight="DemiBold" TextWrapping="Wrap" HorizontalAlignment="{Binding ., Converter={StaticResource MyConverter}}"/>
<StackPanel Orientation="Vertical" Visibility="{Binding Property, Converter={StaticResource MyConverter}}" HorizontalAlignment="Center">
<Image Source="{Binding Property, Converter={StaticResource MyConverter}}" MaxWidth="800" MaxHeight="200" Visibility="{Binding Property, Converter={StaticResource MyConverter}}"/>
<Image gif:ImageBehavior.AnimatedSource="ImageSource" Width="200" MaxHeight="200" Visibility="{Binding Property, Converter={StaticResource MyConverter}}"/>
</StackPanel>
<TextBox Style="{StaticResource MyStyle}" Text="{Binding ., Converter={StaticResource MyConverter}}" FontSize="14" TextWrapping="Wrap" VerticalAlignment="Stretch" HorizontalAlignment="{Binding ., Converter={StaticResource MyConverter}}"/>
</StackPanel>
</Border>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="{Binding ., Converter={StaticResource MyConverter}}" Margin="0, 2, 0, 0" Visibility="{Binding Property, Converter={StaticResource MyConverter}}">
<Image Source="ImageSource" Margin="0,0,0,5" MaxHeight="10" VerticalAlignment="Center"/>
<TextBox Style="{StaticResource MyStyle}" Text="{Binding Property, Converter={StaticResource MyConverter}}" VerticalAlignment="Center" FontSize="10" TextWrapping="Wrap"/>
</StackPanel>
</StackPanel>
</DataTemplate>
Given this, what are some ways to speed things up?

Related

How to change the ImageSource value of the ImageBrush in the DataTemplate

Am requesting for help on how i can dynamically change the value of the ImageSource for the ImageBrush contained in the DataTemplate.
Below is my XAML Code :
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal">
<TextBlock Text="{x:Bind first_name}"
Name="TxtFirstName"
Margin="10,0,0,0"
FontSize="18" FontWeight="Bold" FontStyle="Italic"/>
<TextBlock Text="{x:Bind last_name}"
Name="TxtLastName"
Margin="10,0,0,0"
FontSize="18" FontWeight="Bold" FontStyle="Italic"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Margin="0,40,0,0" HorizontalAlignment="Left" >
<Ellipse Width="200" Height="200" Name="ProfilePicEllipse">
<Ellipse.Fill>
<ImageBrush x:Name="ProfilePic"
ImageSource="{x:Bind image_url}" />
</Ellipse.Fill>
</Ellipse>
<Image x:Name="ResultImage" Stretch="UniformToFill"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Margin="0,40,0,0">
<TextBlock Text= "{x:Bind profile}"
VerticalAlignment="Center"
Margin="10,0,0,0"
FontSize="18" />
</StackPanel>
</StackPanel>
</ScrollViewer>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Not sure what the actual problem is.
But seeing you are already binding the source to a property, you can always change the value of that in your code.
Do note that nothing will change on screen if you don't put Mode=OneWay to it. Because x:Bind default setting is Mode:OneTime
So instead of ImageSource="{x:Bind image_url}" put ImageSource="{x:Bind image_url, Mode=OneWay}"

On few laptops, WPF Data Grid button does not trigger corresponding bound command function in ModelView

This is my view code sample,
<DataGrid Margin="0,0,0,0" Name="gdProcessDetails" ItemsSource="{Binding AttachmentList}" >
<DataGrid.Columns>
<DataGridTemplateColumn Width="670" IsReadOnly="True" x:Name="btnMemeberDelete" MaxWidth="670" Selector.IsSelected="True">
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="Attach File" Width="650" TextWrapping="Wrap" FontFamily="Arial Unicode MS" FontSize="16" TextAlignment="Center" FontWeight="Bold" />
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,2" Width="670" Height="40">
<Border BorderBrush="#FF8D7C7C" BorderThickness="1">
<TextBlock Name="txtFilePath" Text="{Binding UploadedFileName, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" Height="32" FontSize="16" FontFamily="Arial Unicode MS" Margin="10,0,5,0" MinWidth="500" MaxWidth="500" />
</Border>
<Button Height="32" HorizontalAlignment="Center" Margin="5,5,0,0" Name="btnUploadDoc" VerticalAlignment="Top" Command="{Binding ElementName=CertificateControl, Path= DataContext.UploadDocCommand}" CommandParameter ="{Binding ElementName=btnUploadDoc}" MinWidth="80">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Browse" FontSize="16" FontFamily="Arial Unicode MS" Margin="0,0,5,0" MaxWidth="100" TextWrapping="Wrap" />
</StackPanel>
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Data context of this View has 'UploadDocCommand' Icommand property. This is working fine on most of the machine. But on few laptops, clicking on this button does nothing. Any help would be much appreciated. Same result on all over the application wherever Buttons are used inside DataGrid/toolkit:DataGrid. Thanks in advance.
UPDATE : Happens only on 4.0 framework machine
This issue was happening only with Framework 4.0. I have fixed this using RelativeSource instead of ElementName. Changed the button Command property as below and worked. Thanks for all your help.
<Button Height="32" HorizontalAlignment="Center" Margin="5,5,0,0" Name="btnUploadDoc" VerticalAlignment="Top" Command="{Binding DataContext.UploadDocCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" CommandParameter ="{Binding ElementName=btnUploadDoc}" MinWidth="80">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Browse" FontSize="16" FontFamily="Arial Unicode MS" Margin="0,0,5,0" MaxWidth="100" TextWrapping="Wrap" />
</StackPanel>
</Button>

ListBox constant CPU usage

I noticed my application is using about 15% of the CPU constantly when I have a ListBox visible.
I tried using Redgate's ANTS Performance Profiler but I did not manage to find the origin of this CPU-usage. Nothing is being updated so I think this is very strange.
Here is the XAML-code for the ListBox:
<ListBox x:Name="MusicList" ItemsSource="{Binding}" MouseDoubleClick="MusicList_MouseDoubleClick" PreviewMouseWheel="MusicList_PreviewMouseWheel" PreviewMouseLeftButtonDown="MusicList_PreviewMouseLeftButtonDown" TextSearch.TextPath="name" KeyDown="MusicList_KeyDown" Background="#3F181818" Margin="0,175,0,0" BorderThickness="0,1,0,0" ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderBrush="#FF282828">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="88">
<Border Height="64" Width="64" Margin="12,12,0,12">
<Image Stretch="UniformToFill" Source="{Binding Path=album.albumart, IsAsync=True}"/>
</Border>
<StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="0,10,0,0">
<TextBlock Text="{Binding Path=name, IsAsync=True, Mode=OneTime}"
Margin="10,0,0,0" Width="300" Height="40"
TextTrimming="WordEllipsis" TextWrapping="Wrap"
FontSize="16" HorizontalAlignment="Left"
Foreground="White"/>
<TextBlock Text="{Binding Path=album.name, IsAsync=True, Mode=OneTime}"
Margin="10,-15,0,0" Width="300" Height="20"
TextTrimming="WordEllipsis"
HorizontalAlignment="Left"
FontSize="14" Opacity="0.49" Foreground="White"/>
<TextBlock Text="{Binding Path=artistname, IsAsync=True, Mode=OneTime}"
Margin="10,2,0,0" Width="300"
TextTrimming="WordEllipsis"
HorizontalAlignment="Left"
FontSize="12" Opacity="0.49" Foreground="White"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I do have about 500 items in the listbox itself, but I assume DataViritualization is on, since scrolling makes it look like new items are being drawed.
Does anyone know why this is happening?

Stretching of Border's width for ListBoxItem

I have wrote some class, named as Employe. Employees collection I set as source for ListBox WPF control. I have wrote such template for ItemTemplate:
<ResourceDictionary>
<DataTemplate x:Key="tmpEmploye">
<Border BorderThickness="3" BorderBrush="Gray" CornerRadius="5"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Surname}"
HorizontalAlignment="Stretch" Margin="2"
FontWeight="Bold" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Path=Name}"
HorizontalAlignment="Stretch" Margin="2"/>
<TextBlock Text="{Binding Path=Patronymic}"
HorizontalAlignment="Stretch" Margin="2"
TextWrapping="Wrap"/>
</StackPanel>
<TextBlock Text="{Binding Path=Post}" Foreground="Gray"
HorizontalAlignment="Stretch" Margin="2"
FontStyle="Italic" TextWrapping="Wrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ResourceDictionary>
Each item has border. The border must be expanded according width of ListBox. I set HorizontalAlignment="Stretch" for Border, but it is not occured as I want.
How can I correct it?
Try this:
<ListBox Name="lbEmployees" ItemTemplate="{StaticResource tmpEmploye}"
HorizontalContentAlignment="Stretch"
/>

Listbox No Scrollbar

I have been up and down looking on the internet and many people seem to have this problem but its generally solved by changing the container to a grid, constraining the height etc. etc. I can't to seem to get this to work.
I have an observableCollection thats feeding into a DataTemplate. I can't for th life of me get the scrollbar working. Its there but not enabling. Thanks Scott
<TabItem Header="select a call" x:Name="TabActiveCalls" Style="{DynamicResource MyTabItem}" FontFamily="QuickType">
<Grid Margin="0.125,0.412,3.125,0" Height="471" HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Width="839.14" HorizontalAlignment="Left" VerticalAlignment="Top" Height="56">
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" Margin="0,0,10,0" Width="741.14">
<StackPanel Height="28" Orientation="Horizontal" Width="733.14" HorizontalAlignment="Left">
<TextBlock x:Name="txtHistoryFound" TextWrapping="Wrap" Text="*" Foreground="#FFE20A0A" Visibility="Collapsed"/>
<TextBlock TextWrapping="Wrap" Text="filter by:" Margin="5,0,10,0" Foreground="#FF585AD4" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock TextWrapping="Wrap" Text="call no" Margin="5,0,2,0" VerticalAlignment="Center" Foreground="#FF5E88DA"/>
<TextBox Template="{StaticResource TextBoxBaseControlTemplate}" x:Name="searchCallNo" TextChanged="searchCallNo_TextChanged" TextWrapping="Wrap" Width="67" Foreground="#FF1341B1" TextAlignment="Center" Margin="5,0,10,0" Height="22" VerticalAlignment="Center" />
<TextBlock TextWrapping="Wrap" Text="postcode" Margin="5,0,2,0" VerticalAlignment="Center" Foreground="#FF5E88DA"/>
<TextBox Template="{StaticResource TextBoxBaseControlTemplate}" x:Name="searchPostcode" TextWrapping="Wrap" Width="67" Foreground="#FF1341B1" TextAlignment="Center" Margin="5,0,10,0" Height="22" VerticalAlignment="Center"/>
<TextBlock Height="23" x:Name="txtSiteName" FontSize="16" Foreground="#FF0E7C0B" Width="409" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0" TextAlignment="Right" Text="Airedale International Ltd" />
</StackPanel>
<StackPanel Width="733.14" HorizontalAlignment="Left">
<Border Height="21" Margin="5,6,8,0" CornerRadius="3,3,0,0" BorderThickness="1" BorderBrush="#FFC0BABA">
<StackPanel Orientation="Horizontal" Background="#FFD0D5DE">
<TextBlock TextWrapping="Wrap" Text="CALL NO. / DATE DUE/ CUSTOMER" Margin="5,0,0,0" Foreground="{DynamicResource ListTitle}" FontSize="10.667" VerticalAlignment="Center"/>
<TextBlock TextWrapping="Wrap" Text="ENGINEER / ADDRESS" Margin="114,0,0,0" Foreground="{DynamicResource ListTitle}" VerticalAlignment="Center"/>
<TextBlock TextWrapping="Wrap" Text="REPORT" Margin="43,0,0,0" Foreground="{DynamicResource ListTitle}" RenderTransformOrigin="2.543,0.429" VerticalAlignment="Center"/>
<TextBlock TextWrapping="Wrap" Text="CALL" Margin="28,0,0,0" Foreground="{DynamicResource ListTitle}" RenderTransformOrigin="2.543,0.429" VerticalAlignment="Center"/>
<TextBlock TextWrapping="Wrap" Text="POSITION" Margin="43,0,0,0" Foreground="{DynamicResource ListTitle}" RenderTransformOrigin="2.543,0.429" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
<Image Height="56" Width="90" Source="/ComfortReportEng;component/Media/Images/comfort_group.png"/>
</StackPanel>
<ListBox ItemTemplate="{StaticResource DataTemplateReportList}" ItemsSource="{Binding Source={StaticResource cvsReportList}}"
Margin="5,56,8,0" MaxHeight="415" Height="415" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True"/>
</Grid>
</TabItem>
many thanks for getting back. Here is my DataTempate
<DataTemplate x:Key="DataTemplateReportList">
<Border Margin="0,2,0,0" BorderThickness="1" BorderBrush="#FFA19C9C" CornerRadius="3,3,0,0" Width="810.52" Height="50" >
<Grid Background="#FF737B89" Height="48" >
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" Width="274" VerticalAlignment="Top" >
<StackPanel Height="23" Orientation="Horizontal" Margin="0">
<TextBlock TextWrapping="Wrap" Text="{Binding CallNo, Mode=TwoWay}" Foreground="#FF7DF51E" Margin="5,0,0,0" FontFamily="Verdana"/>
<TextBlock TextWrapping="Wrap" Text="{Binding DateDue, Mode=TwoWay, StringFormat=d}" Foreground="White" Margin="5,0,0,0" FontFamily="Verdana"/>
</StackPanel>
<StackPanel Height="23" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Text="{Binding CompanyName, Mode=TwoWay}" Foreground="#FFFFEA00" Margin="5,0,0,0" FontFamily="Verdana"/>
</StackPanel>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="456" Orientation="Vertical" Height="46" Margin="274,1,0,1" VerticalAlignment="Top">
<StackPanel Height="23" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Text="{Binding EngineerName, Mode=TwoWay}" Foreground="#FFCAE5C6" Margin="5,0,0,0" FontFamily="Verdana" Width="140"/>
<TextBlock TextWrapping="Wrap" Text="{Binding ReportStatus, Mode=TwoWay}" Foreground="#FF7DF51E" Margin="20,0,0,0" FontFamily="Verdana" Width="50"/>
<TextBlock TextWrapping="Wrap" Text="{Binding CallStatus, Mode=TwoWay}" Foreground="#FF7DF51E" Margin="20,0,0,0" FontFamily="Verdana" Width="50"/>
<TextBlock TextWrapping="Wrap" Text="{Binding Position, Mode=TwoWay}" Foreground="White" Margin="20,0,0,0" FontFamily="Verdana" Width="50"/>
</StackPanel>
<StackPanel Height="23" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Text="{Binding Address, Mode=TwoWay}" Foreground="#FFFFEA00" Margin="5,0,0,0" FontFamily="Verdana" Width="483.12"/>
</StackPanel>
</StackPanel>
<Grid Width="56" HorizontalAlignment="Right" Margin="0,0,12.52,0" VerticalAlignment="Top">
<Image Name="imgInfo" Source="/ComfortReportEng;component/Media/Images/Info4.png" Margin="24,8,0,0" Cursor="Hand" MouseLeftButtonDown="imgInfo_MouseLeftButtonDown"/>
</Grid>
</Grid>
</Border>
</DataTemplate>
Must be a bug. I have the following only..
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ComfortReportEng.Views.EngineerReport.EngineerReport"
Title="Engineer Report" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" SizeToContent="WidthAndHeight" >
<Window.Resources>
<CollectionViewSource x:Key="cvsReportList"/>
</Window.Resources>
<Grid Margin="0.125,0.412,3.125,0" Height="471">
<ListBox Margin="23,64,3,0" Width="834.14" ItemsSource="{Binding Source={StaticResource cvsReportList}}"
x:Name="lbReportList" SelectionChanged="lbReportList_SelectionChanged" Background="#FFEEEFE4" />
</Grid>
and code is
private void LoadReportList()
{
int number = 0;
List<int> myNumbers = new List<int>();
while (number < 80)
{
myNumbers.Add(number);
number += 1;
}
_cvsReportList = (CollectionViewSource)(this.FindResource("cvsReportList"));
_cvsReportList.Source = myNumbers;
}
This was copied over from another project. Completely confused. Please don't worry. It's not a logical problem. Please take this as a close call with no solution. Cheers again Scott
Just to give this completeness. I am not sure why this happens but here is it.
if (System.Environment.MachineName == "SCOTT-PC")
{
this.txtUserName.Text = "Scott Fisher";
this.txtPassword.Password = "palace";
//LoginOK();
}
else
Keyboard.Focus(this.txtUserName);
If I clear the comments on LoginOK procedure I will get no scrollbar. With it commented and I interact with the login screen then everything is fine. Finally here is the code for the LoginOK.
if (LoginService.CheckLogin(txtUserName.Text, txtPassword.Password.ToString()))
{
Helpers.User.ThisUser = this.txtUserName.Text;
EngineerReport.EngineerReport engReport = new EngineerReport.EngineerReport()
{
Owner = Window.GetWindow(this),
WindowStartupLocation =
System.Windows.WindowStartupLocation.
CenterOwner
};
this.Hide();
engReport.ShowDialog();
}
else
{
this.txtPassword.Password = "";
this.txtPassword.Focus();
}
Can you provide you DataTemplate as I believe I have just managed to mock up what you are trying to achieve and I have scrollbars visible and working form the start.
Here is the xaml that I used for the DataTemplate for the ListBox:
<ListBox DataContext="{StaticResource MusicData}" ItemsSource="{Binding XPath=Album}">
<ListBox.ItemTemplate>
<DataTemplate>
<ListBoxItem>
<StackPanel Orientation="Horizontal" >
<TextBlock>No.</TextBlock>
<TextBlock Text="{Binding XPath=No}"></TextBlock>
<TextBlock>Title</TextBlock>
<TextBlock Text="{Binding XPath=Title}"></TextBlock>
</StackPanel>
</ListBoxItem>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Hope this helps.
I also found a piece of code I used a while back and this might help. You can try setting the ItemsPanelTemplate:
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Visible" />
</StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
This will work with any items control as stated in this article:
http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemcontainerstyle.aspx
One final thing I can suggest is to create your own ControlTemplate for the ListBox Like so:
<ListBox.Template>
<ControlTemplate>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ListBox.Template>

Categories

Resources