为什么我的WPF窗口加载缓慢?

时间:2013-06-11 19:58:59

标签: c# wpf

我正在尝试设计一个非常简单的界面,它显示了许多图像,然后是评级按钮。这是XAML。

   <Window x:Class="ASU_Evaluation2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local ="clr-namespace:ASU_Evaluation2"
        Title="MainWindow" Height="686" Width="1154" Loaded="Window_Loaded" Closing="Window_Closing">

    <Grid Name="ReviewData" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200*"/>
            <ColumnDefinition Width="205"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="474*" />
            <RowDefinition Height="25*" />
        </Grid.RowDefinitions>

        <StackPanel Grid.Column="1" Grid.RowSpan="2">

            <ToggleButton Content="Cell is good" Name="tbGoodCell" Height="30" Margin="1,1" IsChecked="{Binding Cell_Good}"  Width="200"/>
            <ToggleButton Content="Recon is good" Name="tbReconGood" Height="30" Margin="1,1" IsChecked="{Binding Recon_Good}"  Width="200"/>
            <ToggleButton Content="Stain is good" Name="tbStainCell"  Height="30" Margin="1,1" IsChecked="{Binding GoodStain}"  Width="200"/>
            <ToggleButton Content="Recon Clipped" Name="tbReconClipped"  Height="30" Margin="1,1" IsChecked="{Binding Clipping}"  Width="200"/>
            <ToggleButton Content="Interesting" Name="tbInteresting"  Height="30" Margin="1,1" IsChecked="{Binding Interesting}"   Width="200"/>
            <ToggleButton Content="Background Noise" Name="tbNoisy"  Height="30" Margin="1,1" IsChecked="{Binding Noisy}"  Width="200"/>
            <ToggleButton Content="Has Rings" Name="tbRings"  Height="30" Margin="1,1" IsChecked="{Binding Rings}"  Width="200"/>
            <Label Content="Interfering Object" Margin="1,10,1,1"></Label>

            <ListBox Name="tbInterferingObject"  Height="70" SelectedIndex="{Binding InterferingObject}"  Width="200">
            <ListBoxItem>None          </ListBoxItem>
                <ListBoxItem>Close         </ListBoxItem>
                <ListBoxItem>Far           </ListBoxItem>
                <ListBoxItem>Side    </ListBoxItem>
            </ListBox>

            <Label Content="Comments"/>
            <TextBox Margin="1,5" Height="400" Name="Comments" Text="{Binding Comments}" Width="200"/>

        </StackPanel>

        <ComboBox Grid.Row="2" Grid.Column="0" x:Name="themes" Width="150" Height="20" SelectionChanged="themes_SelectionChanged" SelectedIndex="0" />
        <TabControl Grid.Column="0"  Name="tabControl1" >
            <TabItem Header="Recon View" Name="tabItem1">
                <Grid Height="612" Width="934">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="225" />
                        <ColumnDefinition Width="225" />
                        <ColumnDefinition Width="225" />
                        <ColumnDefinition Width="225*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="291" />
                        <RowDefinition Height="291" />
                    </Grid.RowDefinitions>
                    <Image Grid.Column="0" Grid.Row="0"   Margin="2,2" Name="MIP_Image" Height="210" Width="210"/>
                    <Image Grid.Column="1" Grid.Row="0"   Margin="2,2" Name="Axial_Image" Source="{Binding Axial_Image}" Height="210" Width="210"/>
                    <Image Grid.Column="0" Grid.Row="1"   Margin="2,2" Name="Sag_Image" Source="{Binding Sag_Image}" Height="210" Width="210"/>
                    <Image Grid.Column="1" Grid.Row="1"   Margin="2,2" Name="Z_Image" Source="{Binding Z_Image}" Height="210" Width="210"/>
                    <Image Grid.Column="2" Grid.Row="0"   Margin="2,2" Name="Fly_Through"  Height="210" Width="210"/>
                    <Image Grid.Column="2" Grid.Row="1" Grid.ColumnSpan="2" Margin="2,2" Name="Background"  Source="{Binding Background}" Height="250" Width="450"/>
                </Grid>
            </TabItem>
            <TabItem Header="Alignment View" Name="tabItem2">
                <Grid >
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="460" />
                        <ColumnDefinition Width="460" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="190" />
                        <RowDefinition Height="190" />
                        <RowDefinition Height="190" />
                    </Grid.RowDefinitions>
                    <Image Grid.Column="0" Grid.Row="0"   Margin="2,2" Name="PP1"   Source="{Binding PP1}" Width="460" Height="190" />
                    <Image Grid.Column="0" Grid.Row="1"   Margin="2,2" Name="PP2"   Source="{Binding PP2}" Width="460" Height="190" />
                    <Image Grid.Column="0" Grid.Row="2"   Margin="2,2" Name="PP3"   Source="{Binding PP3}" Width="460" Height="190" />
                    <Image Grid.Column="1" Grid.Row="0" Grid.RowSpan="3"   Margin="2,2" Name="Centering" HorizontalAlignment="Center" VerticalAlignment="Center" Width="400" MinHeight="400"  Source="{Binding Centering}"/>

                </Grid>
            </TabItem>
            <TabItem Header="Stack View" Name="tabItem3" GotFocus="tabItem3_GotFocus">
                <Grid >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="418*" />
                        <RowDefinition Height="24*" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="581*" />
                        <ColumnDefinition Width="207*" />
                    </Grid.ColumnDefinitions>
                    <Image Name="Stack_Image" VerticalAlignment="Center" HorizontalAlignment="Center" MinHeight="100" MinWidth="100"   Height="400" Margin="98,26,82,15" Width="400" />
                    <ScrollBar Grid.Column="1" Height="353" HorizontalAlignment="Left" Margin="36,50,0,0" Name="StackZPosition" VerticalAlignment="Top" Width="17" ValueChanged="StackZPosition_ValueChanged" />
                    <Label Content="Z Position" Grid.Column="1" Height="27" HorizontalAlignment="Left" Margin="13,17,0,0" Name="label1" VerticalAlignment="Top" Width="79" />
                    <ProgressBar Grid.Row="1" Height="14" HorizontalAlignment="Left" Margin="95,4,0,0" Name="StackProgress" VerticalAlignment="Top" Width="404" />
                </Grid>
            </TabItem>
            <TabItem Header="Othogonal View" Name="tabItem4">
                <Grid >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="418*" />
                        <RowDefinition Height="24*" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="581*" />
                        <ColumnDefinition Width="207*" />
                    </Grid.ColumnDefinitions>

                </Grid>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

绑定的类看起来像这样

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Threading.Tasks;
using System.Drawing;

namespace ASU_Evaluation2
{
class DatasetExample
{
      public string Date { get { return "3/3/3"; } }
    public ImageSource ExampleImage
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\CrossSections_X___TIK.jpg";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }
    public bool Recon_Succeeded { get { return true; } }
    public bool Cell_Good
    {
        get;
        set;
    }
    public bool Recon_Good
    {
        get;
        set;
    }
    public string DatasetName { get; private set; }
    public string TopDirectory { get; private set; }


    string VGFolder;
    string StorageFolder;
    string DehydrateFolder;
    string BackupFolder;
    string StackFolder;
    string StackReportFilePath;

    private void BuildPaths()
    {
        string dirName = Path.GetFileNameWithoutExtension(TopDirectory);
        //return dirName;
        string[] parts = dirName.Split('_');
        string Prefix = parts[0];
        string Year = parts[1].Substring(0, 4);
        string month = parts[1].Substring(4, 2);
        string day = parts[1].Substring(6, 2);

        VGFolder = Path.Combine(@"y:\", Prefix + "\\" + Year + month + "\\" + day + "\\" + dirName);
        StorageFolder = Path.Combine(@"z:\", Prefix + "\\" + Year + month + "\\" + day + "\\" + dirName);
        DehydrateFolder = Path.Combine(@"e:\", Prefix + "\\" + Year + month + "\\" + day + "\\" + dirName);
        BackupFolder = Path.Combine(@"V:\BackupCompleted\", Prefix + "\\" + Year + month + "\\" + day + "\\" + dirName);

        if (Prefix.ToLower() == "cct001")
        {
            StackFolder = Path.Combine(@"V:\Raw PP\cct001\Absorption\", Year + month + "\\" + day + "\\" + dirName + "\\STACK\\000");
        }
        else
            StackFolder = Path.Combine(@"V:\Raw PP\", Prefix + "\\" + Year + month + "\\" + day + "\\" + dirName + "\\STACK\\000");

        StackReportFilePath = VGFolder + "\\FixedStackReport.xml";
    }

    public DatasetExample(string name, string path)
    {
        DatasetName = name;
        TopDirectory = path;
        GoodStain = true;
        Clipping = false;
        Interesting = false;
        Noisy = false;
        Rings = false;
        InterferingObject = 0;
        Comments = "  ";
        Evaluator = "Brian";
        Cell_Good = true;
        CellType = " ";
        Recon_Good = true;

    }

    public string Evaluator { get; set; }
    public string CellType { get; set; }
    public bool GoodStain { get; set; }
    public bool Clipping { get; set; }
    public bool Interesting { get; set; }
    public bool Noisy { get; set; }
    public bool Rings { get; set; }
    public int  InterferingObject { get; set; }
    public string Comments { get; set; }



    public ImageSource Axial_Image
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\CrossSections_X___TIK.jpg";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }
    public ImageSource Sag_Image
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\CrossSections_Y___TIK.jpg";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }
    public ImageSource Z_Image
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\CrossSections_Z___TIK.jpg";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }


    public void ClearMemory()
    {



    }

    public ImageSource Background
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\background.tif";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }
    public ImageSource PP1
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\projection1.jpg";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }
    public ImageSource PP2
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\projection2.jpg";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }
    public ImageSource PP3
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\projection3.jpg";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }
    public string Centering
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\centering.avi";

            if (File.Exists(exampleImage))
                return exampleImage;
            else
                return "";
        }
    }

    public ImageSource Stack_Image
    {
        get
        {
            string exampleImage = TopDirectory + @"\data\CrossSections_Y___TIK.jpg";

            if (File.Exists(exampleImage))
                return BitmapFrame.Create(new Uri(exampleImage, UriKind.Absolute), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            else
                return null;
        }
    }

}

}

在高端计算机上加载接口需要15-20秒。我试图用Windows SDK运行性能监视器工具,它只是崩溃了。我究竟做错了什么?这是winforms中一项令人尴尬的简单任务。

1 个答案:

答案 0 :(得分:2)

首先,您的属性每次调用时都会返回ImageSource的新实例。你应该避免这种情况。

  • 修复1:

    private ImageSource sag_Image;
    public ImageSource Sag_Image
    {
        get
        {
            if (sag_Image != null)
                return sag_Image;
    
            //... Etc your code
    
            sag_Image = //Assign the backing field to use it later.
        }
    }
    

您应该Freeze your Freezables(例如ImageSource)。

  • 修复2:

    public ImageSource Sag_Image
    {
        get
        {
            if (sag_Image != null)
                return sag_Image;
    
            //... Etc your code
    
            sag_Image = //Assign the backing field to use it later.
    
            sag_Image.Freeze(); //Notice the Freeze() method.
        }
    }
    
  • 修复3:

    异步。所有需要10多毫秒才能完成应该的操作都是异步的。

第三,您的XAML看起来像是从Visual Studio设计器获得的,并且还有一些可疑的东西,例如ScrollBar.ValueChanged事件。那是做什么的?发布相关代码,可能是您需要的屏幕截图。我确信有一个正确的方法来做WPF,它不涉及可怕的代码隐藏winforms类型的黑客,并没有显示你在这里描述的这些性能问题。