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

本文关键字:缓慢 加载 窗口 我的 WPF 为什么 | 更新日期: 2023-09-27 18:17:52

我正在尝试设计一个非常简单的界面,显示一些图像,然后评级按钮。这是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运行性能监控工具,它只是崩溃了。我做错了什么?

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

首先,每次调用属性时都会返回一个新的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.
        }
    }
    

你应该冷冻你的冷冻食品(如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:

    异步。 应该是异步的

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