4

我是 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>

当我在 IDE 中运行我的应用程序时,窗口打开需要 5 秒钟。一旦打开,它会快速重绘(当我调整它的大小时),一切看起来都很活泼。

我的电脑不是最快的:AMD 双核 2.3GHz、2GB RAM、XP 32 位操作系统、板载视频。

我可以放置 25 个按钮,而不是日历,并且加载时间不到 1 秒。

我正在尝试在 MS Outlook 日历的日视图中创建类似于小月历的内容,如下所示:

在此处输入图像描述

所以我想我可以使用 WrapPanel 并在调整大小时添加/删除日历控件。我可能不需要 25,但即使是 9 或 12,它也比我想象的要慢(我有一个旧版 Win32 应用程序,它在不到 1 秒的时间内显示 18 个这样的日历)。

我的问题是:

日历控件是否因为某种设计而变慢——要么是一个糟糕的设计,要么只是不是为这种用途而设计的,还是因为它试图显示大量数据/控件/信息而变慢?

如果我麻烦地创建自己的控件,假设我使用了一个好的设计(欢迎一般想法),它会更快,还是这只是 WPF 的“典型”?

我可以做些什么来使默认的日历控件更快地用于这种用法?

4

3 回答 3

6

本身不是一个答案,但添加它可以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>

编辑:

这种视觉变化不会影响控件的功能。所有 Calendar's Day 项目仍然是Selectable,您可以绑定该Calendar.SelectedDate属性。

只是没有视觉指示表明选择了某个项目,因此单击日期似乎无济于事。

只需将其添加到您的 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>

您可以使用ControlTemplateTriggers来添加视觉效果。尽管请记住模板越复杂,加载所需的时间就越长。

于 2013-08-30T20:58:30.093 回答
3

这将使您了解日历与使用 Snoop 的按钮的区别。是的,我们确实预计很多日历会花费更多的渲染时间。如果您需要使用很多,我会尝试创建自己的更简单和/或虚拟化它们

这是一个按钮,3个孩子...

在此处输入图像描述

这是一个日历,522 个孩子。请注意,CalendarButtons我没有展开的每个仍然有 9 个孩子

在此处输入图像描述 在此处输入图像描述

于 2013-08-30T20:41:29.227 回答
0

我将更新它,因为我有时间完成这个新控件,但到目前为止,我向自己证明了我可以在一个窗口中拥有大量控件并且仍然可以快速加载它。在这种情况下,1050 个文本块(7 列 * 6 行 * 我的用户控件的 25 个实例),我的窗口在不到 1 秒的时间内加载。

到目前为止,这是我的简单用户控件:

<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>

我将其中的 25 个放在 WrapPanel 中,加载时间不到 1 秒。我仍然需要向我的用户控件添加更多控件和样式,但我认为它仍然会比内置的日历控件快得多(我希望如此)。

ps-即使窗口上有 50 个我的用户控件副本,它也会在大约 1 秒内加载。

于 2013-08-30T23:53:44.100 回答