I'm new to WPF, and trying to get an idea of just how much slower it might be. I started a new WPF app, in Visual Studio 2010 (.NET 4), and created this XAML:
我是WPF的新手,并试图了解它可能会有多慢。我在Visual Studio 2010(.NET 4)中启动了一个新的WPF应用程序,并创建了这个XAML:
<Window x:Class="CalendarTest1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="800" Width="1000">
<WrapPanel>
<Calendar />
<Calendar />
<Calendar />
...repeats for a total of 25 calendar objects...
</WrapPanel>
</Window>
When I run my application, in the IDE or not, it takes 5 seconds for the window to open. Once open, it redraws quickly (as I resize it) and everything seems snappy.
当我运行我的应用程序时,无论是否在IDE中,窗口打开需要5秒钟。一旦打开,它会快速重绘(当我调整大小时),一切看起来都很活泼。
My PC isn't the fastest: AMD Dual Core 2.3GHz, 2GB RAM, XP 32-bit OS, on-board video.
我的PC不是最快的:AMD双核2.3GHz,2GB RAM,XP 32位操作系统,板载视频。
I can place 25 buttons, instead of Calendars, and that loads in less than 1 second.
我可以放置25个按钮,而不是日历,并在不到1秒的时间内加载。
I'm trying to create something like the little month calendars in the day view in the MS Outlook calendar, like this:
我正在尝试在MS Outlook日历中创建像日视图中的小月历这样的内容,如下所示:
So I was thinking I could use a WrapPanel and add/remove Calendar controls as it resizes. I might not need 25, but even with 9 or 12 it is slower than I would think (I have a legacy Win32 app that displays 18 calendars like this in less than 1 second).
所以我想我可以使用WrapPanel并在调整大小时添加/删除Calendar控件。我可能不需要25,但即使有9或12它比我想象的慢(我有一个遗留的Win32应用程序,在不到1秒的时间内显示18个这样的日历)。
My questions are:
我的问题是:
Is the Calendar control slow because of a certain design -- either a bad design, or just not designed for this usage, or is it just slow because it is trying to display a lot of data/controls/info?
由于某种设计,日历控件是否会变慢 - 或者设计不好,或者仅仅是为此用途而设计,还是因为它试图显示大量数据/控件/信息而变慢?
If I go to the trouble to create my own control, assuming I use a good design (general ideas welcome), can it be a lot faster, or is this just "typical" for WPF?
如果我去创建我自己的控件的麻烦,假设我使用一个好的设计(一般的想法欢迎),它可以更快,或者这只是WPF的“典型”?
Is there something I can do to make the default Calendar control faster for this usage?
我可以做些什么来使这个用途的默认日历控件更快?
3 个解决方案
#1
6
Not an answer per se, but adding this to Window.Resources
reduced the load time 50% in my machine (which is now under 1 second for 25 calendars)
本身不是答案,但将其添加到Window.Resources可以减少我机器的加载时间50%(25个日历现在不到1秒)
<Window.Resources>
<Style TargetType="CalendarDayButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CalendarDayButton">
<ContentPresenter ContentSource="Content" Margin="2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Calendar">
<Setter Property="CalendarDayButtonStyle" Value="{StaticResource {x:Type CalendarDayButton}}"/>
</Style>
</Window.Resources>
Edit:
This visual change does not affect the control's functionality. All the Calendar's Day items are still Selectable
, and you can bind the Calendar.SelectedDate
property.
此视觉更改不会影响控件的功能。所有日历日项目仍然是可选项,您可以绑定Calendar.SelectedDate属性。
There's just no visual indication that an item is selected, therefore clicking on the days seems to do nothing.
没有视觉指示选择了一个项目,因此点击日期似乎什么都不做。
Just add this to your ControlTemplate:
只需将其添加到ControlTemplate:
<ControlTemplate TargetType="CalendarDayButton">
<ContentPresenter ContentSource="Content" Margin="2"/>
<ControlTemplate.Triggers>
<!-- Set The FontWeight to "Bold" when Selected -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
You can play around with this ControlTemplate
and its Triggers
to add visual effects. Though keep in mind the more complex the template, the longer it will take to load.
您可以使用此ControlTemplate及其触发器来添加视觉效果。虽然请记住模板越复杂,但加载时间越长。
#2
3
This will give you an idea of what a calendar is versus a button using Snoop. Yes, we do expect a lot of calendars to take a lot more rendering time. If you need to use a lot of them, I'd attempt to create your own that's simpler and/or virtualize them
这将让您了解日历与使用Snoop的按钮的对比情况。是的,我们确实希望很多日历可以花费更多的渲染时间。如果你需要使用它们很多,我会尝试创建你自己的更简单和/或虚拟化它们
Heres a button, 3 children...
继承人一个按钮,3个孩子......
And heres a Calendar, 522 children. Notice each of the CalendarButtons
I didn't expand still have 9 children each
还有一个日历,522个孩子。请注意,我没有展开的每个CalendarButton仍然有9个孩子
#3
0
I'll update this as I have time to finish up this new control, but so far I proved to myself that I can have a large number of controls in a window and still have it load quickly. In this case, 1050 TextBlocks (7 columns * 6 rows * 25 instances of my user control), and my window loads in less than 1 second.
我会更新这个,因为我有时间完成这个新控件,但到目前为止,我向自己证明了我可以在窗口中拥有大量控件并且仍然可以快速加载。在这种情况下,1050个TextBlocks(7列* 6行* 25个我的用户控件实例),我的窗口加载时间不到1秒。
Here is my simple user control so far:
到目前为止,这是我的简单用户控件:
<UserControl x:Class="FastCalendar.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FastCalendar"
xmlns:vm="clr-namespace:FastCalendar.ViewModels"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Margin="5">
<UserControl.Resources>
<vm:MainViewModel x:Key="ViewModel" />
</UserControl.Resources>
<ItemsControl Width="180" Height="170" ItemsSource="{Binding Path=Days, Source={StaticResource ViewModel}}">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Row" Value="{Binding Path=Row}" />
<Setter Property="Grid.Column" Value="{Binding Path=Column}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Path=Day}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</UserControl>
I placed 25 of those inside a WrapPanel, and it loads in less than 1 second. I still need to add more controls and styles to my user control, but I'm thinking it will still be much faster than the built-in Calendar control (I hope).
我将其中25个置于WrapPanel内,并在不到1秒的时间内加载。我仍然需要为我的用户控件添加更多控件和样式,但我认为它仍然比内置Calendar控件(我希望)快得多。
p.s.-Even with 50 copies of my user control on the window, it loads in about 1 second.
p.s.-即使在窗口上有50份我的用户控件,它也会在大约1秒内加载。
#1
6
Not an answer per se, but adding this to Window.Resources
reduced the load time 50% in my machine (which is now under 1 second for 25 calendars)
本身不是答案,但将其添加到Window.Resources可以减少我机器的加载时间50%(25个日历现在不到1秒)
<Window.Resources>
<Style TargetType="CalendarDayButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CalendarDayButton">
<ContentPresenter ContentSource="Content" Margin="2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Calendar">
<Setter Property="CalendarDayButtonStyle" Value="{StaticResource {x:Type CalendarDayButton}}"/>
</Style>
</Window.Resources>
Edit:
This visual change does not affect the control's functionality. All the Calendar's Day items are still Selectable
, and you can bind the Calendar.SelectedDate
property.
此视觉更改不会影响控件的功能。所有日历日项目仍然是可选项,您可以绑定Calendar.SelectedDate属性。
There's just no visual indication that an item is selected, therefore clicking on the days seems to do nothing.
没有视觉指示选择了一个项目,因此点击日期似乎什么都不做。
Just add this to your ControlTemplate:
只需将其添加到ControlTemplate:
<ControlTemplate TargetType="CalendarDayButton">
<ContentPresenter ContentSource="Content" Margin="2"/>
<ControlTemplate.Triggers>
<!-- Set The FontWeight to "Bold" when Selected -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
You can play around with this ControlTemplate
and its Triggers
to add visual effects. Though keep in mind the more complex the template, the longer it will take to load.
您可以使用此ControlTemplate及其触发器来添加视觉效果。虽然请记住模板越复杂,但加载时间越长。
#2
3
This will give you an idea of what a calendar is versus a button using Snoop. Yes, we do expect a lot of calendars to take a lot more rendering time. If you need to use a lot of them, I'd attempt to create your own that's simpler and/or virtualize them
这将让您了解日历与使用Snoop的按钮的对比情况。是的,我们确实希望很多日历可以花费更多的渲染时间。如果你需要使用它们很多,我会尝试创建你自己的更简单和/或虚拟化它们
Heres a button, 3 children...
继承人一个按钮,3个孩子......
And heres a Calendar, 522 children. Notice each of the CalendarButtons
I didn't expand still have 9 children each
还有一个日历,522个孩子。请注意,我没有展开的每个CalendarButton仍然有9个孩子
#3
0
I'll update this as I have time to finish up this new control, but so far I proved to myself that I can have a large number of controls in a window and still have it load quickly. In this case, 1050 TextBlocks (7 columns * 6 rows * 25 instances of my user control), and my window loads in less than 1 second.
我会更新这个,因为我有时间完成这个新控件,但到目前为止,我向自己证明了我可以在窗口中拥有大量控件并且仍然可以快速加载。在这种情况下,1050个TextBlocks(7列* 6行* 25个我的用户控件实例),我的窗口加载时间不到1秒。
Here is my simple user control so far:
到目前为止,这是我的简单用户控件:
<UserControl x:Class="FastCalendar.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FastCalendar"
xmlns:vm="clr-namespace:FastCalendar.ViewModels"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Margin="5">
<UserControl.Resources>
<vm:MainViewModel x:Key="ViewModel" />
</UserControl.Resources>
<ItemsControl Width="180" Height="170" ItemsSource="{Binding Path=Days, Source={StaticResource ViewModel}}">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Row" Value="{Binding Path=Row}" />
<Setter Property="Grid.Column" Value="{Binding Path=Column}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Path=Day}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</UserControl>
I placed 25 of those inside a WrapPanel, and it loads in less than 1 second. I still need to add more controls and styles to my user control, but I'm thinking it will still be much faster than the built-in Calendar control (I hope).
我将其中25个置于WrapPanel内,并在不到1秒的时间内加载。我仍然需要为我的用户控件添加更多控件和样式,但我认为它仍然比内置Calendar控件(我希望)快得多。
p.s.-Even with 50 copies of my user control on the window, it loads in about 1 second.
p.s.-即使在窗口上有50份我的用户控件,它也会在大约1秒内加载。