精华内容
下载资源
问答
  • C#获取桌面运行程序名称,C#调用windows api示例
  • 今天中午休息了一会醒来,桌面上的程序名称和文件名全都有了蓝色阴影。于是,上网查找资料予以解决。在一篇文章的指导中,我完成了,其实很简单。  在桌面空白处单击右键 —> 属性(Properties)—> 桌面...

     今天中午休息了一会醒来,桌面上的程序名称和文件名全都有了蓝色阴影。于是,上网查找资料予以解决。在一篇文章的指导中,我完成了,其实很简单。

     在桌面空白处单击右键 —>  属性(Properties)—> 桌面(Desktop) —> 自定义桌面(Customize Desktop...) —> Web,在Web pages下的勾去掉即可。

                                                                                                               

    展开全文
  • C#桌面程序

    2019-09-23 17:05:06
    目录一 VS2019新建WPF程序二 XAML1 概述2 剖析XAML代码3 XAML语法4 XAML对名称空间引用的语法5 窗体的关闭事件Closing 和Closed三 窗口属性1 启动最大化2 删除最大最小化按钮3 标题栏添加图标四 日志五 Grid1 ...

    一 VS2019新建WPF程序

      本节内容来自这里
    在这里插入图片描述
      从工具箱中拖拽一个Button控件,修改显示名称并添加事件,如下图所示:
    在这里插入图片描述
      双击按钮,进入事件代码区域,简单添加一个弹出显示提示文字的对话框代码,如下图所示:
    在这里插入图片描述
      运行,程序创建完毕。

    二 XAML

    1 概述

      XAML是微软创造的一种开发语言,即可拓展应用程序标记语言。扮演了HTML+CSS+JavaScript的角色。

    2 剖析XAML代码

      一个.xaml下会有一个.xaml.cs,.xaml.cs文件会有对应的分部类。XAML标签声明一个元素时对应的内存中的一个对象,最外层的标签元素就是后台代码的分部类。
      在XAML中对象之间的层级关系,要么是并列要么是包含,全部体现在标签的关系上。那在后台类里,我们可以通过using引用其它名称空间,而在XAML代码里,我们通过xmlns特征来定义名称空间,格式如下:
      xmlns:[可选的映射前缀]="名称空间"。看下默认的XAML代码:

    <Window x:Class="PLCSerialPortRecv.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:PLCSerialPortRecv"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            
        </Grid>
    </Window>
    

      可以发现我们有5行代码以xmlns开头,也就是“引用了5个默认的名称空间”。其中x:和mc:开头表示调用上面声明引用的名称空间。
      x:它包含的类都是与解析XAML语言相关。x:Class="MyFirstWpfApplication.MainWindow"表示将当前这个Window这个标签解析成C#类的类名。这也和我们开始验证的其为后台分部类一样。它是x:下的Attribute,只能用于根节点,且根节点的类型要与x:Class所指示的类型(且为分部类)一致。
      补充 x名称空间下的其它Attribute:x:Name:告诉编译器为这个标签生成对应的实例外还要为这个实例声明一个引用变量,变量名就是x:Name的值。还有将XAML标签所对应的对象的Name属性也设为x:Name的值,并注册到UI树上,方便查找。x:FieldModeifer 设置元素可访问级别。x:key 采用键值对等。

    3 XAML语法

      xaml文档是一个树形结构。
      xaml中为对象属性赋值的语法:首先xaml代码不能编写程序的运行逻辑,当我们创建标签对象的时候对其属性进行必要的初始化才有使用意义。为对象属性赋值有两种方法
      1.使用字符串进行简单赋值。即简单的Attribute=Value语法赋值,由于xaml语法限制,Value只能是字符串的值。
      2.使用属性元素进行复杂赋值。属性元素指的是某个标签的一个元素对应这个标签的一个属性,即以元素的形式来表达一个实例的属性。

    4 XAML对名称空间引用的语法

      xmlns:[映射名]=“clr-namespace:类库中名称空间的名字;assembly=类库文件名”

    5 窗体的关闭事件Closing 和Closed

      当窗口关闭时,它会引发两个事件:Closing 和 Closed。
      Closing 在窗口关闭之前引发,它提供一种机制,可以通过这种机制来阻止窗口关闭。 系统会向Closing 事件处理程序传递一个 CancelEventArgs e,该参数实现 Boolean Cancel 属性,将该属性设置为 true 可以阻止窗口关闭。

     private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
     {
         MessageBoxResult result = MessageBox.Show("确定是退出吗?", "询问", MessageBoxButton.YesNo, MessageBoxImage.Question);
         //关闭窗口
         if (result == MessageBoxResult.Yes)
             e.Cancel = false;
         //不关闭窗口
         if (result == MessageBoxResult.No)
             e.Cancel = true;
     }
    

      如果未处理Closing,或者处理但未取消,则窗口将关闭。 在窗口真正关闭之前,会引发 Closed,这时无法阻止窗口关闭。

    三 窗口属性

    1 启动最大化

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //启动最大化
            this.WindowState = System.Windows.WindowState.Maximized;     
        }
    }
    

    2 删除最大最小化按钮

    <Window x:Class="InspectionParser.About"        
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:InspectionParser"
            mc:Ignorable="d"
            ResizeMode="NoResize"
            Title="关于" Height="450" Width="800">
        <Grid>        
        </Grid>
    </Window>
    

    3 标题栏添加图标

      WPF如何给窗体添加图标:https://jingyan.baidu.com/article/6d704a13c995ca68da51ca04.html

    四 日志

      使用 serilog 组件,nuget 安装:
    在这里插入图片描述

    using Serilog;
    using Serilog.Events;
    using Serilog.Core;
    
    class ThreadIdEnricher : ILogEventEnricher
    {
        public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
        {
            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
                    "ThreadId", Thread.CurrentThread.ManagedThreadId));
        }
    }
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            string SerilogOutputTemplate = "{Timestamp:HH:mm:ss}[{Level:u3}]: ({ThreadId}){Message}{NewLine}{Exception}";
            Log.Logger = new LoggerConfiguration()
            .Enrich.With(new ThreadIdEnricher())
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .WriteTo.File($"{AppContext.BaseDirectory}00_Logs/log.log",
                           rollingInterval: RollingInterval.Day, outputTemplate: SerilogOutputTemplate)
            .CreateLogger();
            Log.Information("================start program!!!=================");
        }
    }
    

    五 Grid

      Grid和其他各个Panel比较起来,功能最多也最为复杂。要使用Grid,首先要向RowDefinitions和ColumnDefinitions属性中添加一定数量的RowDefinitions和 ColumnDefinitions元素,从而定义行数和列数;而放置在Grid面板中的控件元素都必须显示采用Row和Column附加属性定义其放置所在的行和列,这两个属性的值都是从0开始的索引数,如果没有显式设置任何行或列,Grid将会隐式地将控件加入在第0行第0列。
      注意:尽管Grid面板被设计成不可见的,但可将Grid.ShowGridLines属性设置为True,从而更清晰的观察Grid面板,方便调试,可以更准确地控制Grid面板如何选择列宽和行高。
      https://www.cnblogs.com/dotnet261010/p/6281915.html

    1 ScrollViewer控件

      内容超过空间,出现滚动条。
      TextWrapping=“Wrap”,超出宽度,自动换行。

    2 Panel分组类控件

    3 groupBox分组框控件

    4 TabControl选项卡控件

    6 StackPanel(堆布局)

      这个布局是比较简单的布局模式,在这个StackPanel容器,控件都是以一列,或者一行的方式来顺序排列。
      StackPanel默认是垂直一列排列,通过设置Orientation这个属性来设置水平一行排序
    在这里插入图片描述
      水平
    在这里插入图片描述
      默认情况下,容器内的控件都是被拉伸的,和容易一样高或者一样宽
      在垂直模式下,按钮都是和屏幕的宽带一样被拉伸,垂直排列,并且是居中显示。
      垂直模式下HorizontalAlignment可以设置“Center,left,right,stretch”4个属性
      如果设置center,那么容器的宽度会和按钮的宽度一样(按钮的宽度默认就是字符内容的长度),并且居中显示
      如果设置Left,那么容器就会显示在屏幕的左侧,宽度和按钮宽度一样,如图示:
    在这里插入图片描述
      在容器内的各个按钮上也可以设置自己的水平排列方式,如果设置Left,那么按钮排列在容器左侧,如果是right,按钮牌子在容器右侧,如果是stretch这个按钮仍然是拉伸显示

    <StackPanel x:Name="StackPanel1" Orientation="Vertical">
            <Button x:Name="btn1" Content="Button1"  HorizontalAlignment="Left"></Button>
            <Button x:Name="btn2" Content="Button2" HorizontalAlignment="Center"></Button>
            <Button x:Name="btn3" Content="Button3" HorizontalAlignment="Stretch"></Button>
            <Button x:Name="btn4" Content="Button4" HorizontalAlignment="Right"></Button>
    </StackPanel>
    

    在这里插入图片描述

    7 DockPanel停靠面板

      DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中。停靠面板类似于WinForm中控件的Dock属性。DockPanel会对每个子元素进行排序,并将根据指定的边进行停靠,多个停靠在同侧的元素则按顺序排序。在DockPanel中,指定停靠边的控件,会根据定义的顺序占领边角,所有控件绝不会交叠。
      默认情况下,后添加的元素只能使用剩余空间,无论对DockPanel的最后一个子元素设置任何停靠值,该子元素都将始终填满剩余的空间。如果不希望最后一个元素填充剩余区域,可以将DockPanel属性LastChildFill设置为false,还必须为最后一个子元素显式指定停靠方向。
      填充整个剩余空间
    在这里插入图片描述

    <Window x:Class="WpfDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="DockPanel面板" Height="237" Width="525" WindowStartupLocation="CenterScreen">
        <DockPanel>
            <Button DockPanel.Dock="Left" Content="ButtonLeft"></Button>
            <Button DockPanel.Dock="Top" Content="ButtonTop"></Button>
            <Button DockPanel.Dock="Right" Content="ButtonRight"></Button>
            <Button DockPanel.Dock="Bottom" Content="ButtonBottom"></Button>
            <Button  Content="ButtonTop"></Button>
        </DockPanel>
    </Window>
    

      最后元素不填充剩余空间
    在这里插入图片描述

    <Window x:Class="WpfDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="DockPanel面板" Height="237" Width="525" WindowStartupLocation="CenterScreen">
        <DockPanel LastChildFill="False">
            <Button DockPanel.Dock="Left" Content="ButtonLeft"></Button>
            <Button DockPanel.Dock="Top" Content="ButtonTop"></Button>
            <Button DockPanel.Dock="Right" Content="ButtonRight"></Button>
            <Button DockPanel.Dock="Bottom" Content="ButtonBottom"></Button>
            <Button  DockPanel.Dock="Top" Content="最后一个Button不填充剩余空间"></Button>
        </DockPanel>
    </Window>
    

    六 GridSplitter

      本节内容来自这里

    七 border

      Border 是一个装饰的控件,此控件绘制一个边框、一个背景,在 Border 中只能有一个子控件,但它的子控件是可以包含多个子控件的 Border 的几个生要的属性:
      1、Background:此WPF Border属性设置 Border 用来绘制背景的 Brush 对象;
      2、BorderBrush:此属性设置 Border 用来绘制边框的 Brush 对象;
      3、BorderThickness:此属性设置 Border 边框的宽度,此属性是一个 Thickness 对象, Thickness 是一个 struct 类型的对象,使用 Thickness 对象可以设置边框每一边的线条的宽度;
      4、CornerRadius:此WPF Border属性设置 Border 的每一个角圆的半径,此属性是一个 CornerRadius 对象,CornerRadius 是一个struct 类型的对象;
      5、Padding:此WPF Border属性设置 Border 里的内容与边框的之间的间隔,此属性是一个 Thickness 对象,可以使用此对象为每一边的间隔进行设置。

    八 属性

    1 窗体初始位置WindowStartupLocation

      当窗口打开时,窗口在相对于桌面的 x 和 y 维度有一个位置。 可以通过分别检查 Left 和 Top 属性来确定此位置。 可以设置这些属性以更改窗口的位置。
      通过将 WindowStartupLocation 属性设置为下面的 WindowStartupLocation 枚举值之一,还可以指定 Window 第一次出现时的初始位置:Manual(默认值)、CenterScreen、CenterOwner。
      如果将起始位置指定为 Manual,并且未设置 Left 和 Top 属性,则 Window 将向 Windows 请求显示的位置。

    2 Margin and Padding

      在界面设计时,Margin 和Padding都是对边距进行限制的,其区别在于“一个主外,一个主内”。
      <font size=3Margin (边缘)是约束控件与容器控件的边距,设置值分别代表左上右下,使用 Margin=“20” 同时指定四个值。
      <font size=3Padding (衬垫)是约束控件内部输入边距的,只有部分控件有此属性。

    3 Grid.ColumnDefinitions和Grid.RowDefinitions

      Grid.RowDefinitions 属性将 Grid 控件分行,属性值为 RowDefinition 标签,每一个 RowDefinition 标签将该 Grid 对象分为一行;
      Grid.ColumnDefinitions 属性将 Grid 控件分列,属性值为 ColumnDefinition 标签,每一个 ColumnDefinition 标签将该 Grid 对象分为一列;
      在给每个方块添加空间时只需指定该控件的 Grid.ColumnGrid.Row 附加属性值,前提是该控件要定义在Grid空间中,否则将找不到这两个属性,也就无法将该控件添加到指定方格中。
      当指定的行或列的值大于Grid的单元格数量时,系统默认为最后一个,比如:

    <Grid x:Name="LayoutRoot" Background="Blue">  
        <Grid.ColumnDefinitions>  
            <ColumnDefinition></ColumnDefinition>  
            <ColumnDefinition></ColumnDefinition>  
        </Grid.ColumnDefinitions>  
        <Grid.RowDefinitions>  
            <RowDefinition></RowDefinition>  
            <RowDefinition></RowDefinition>  
            <RowDefinition></RowDefinition>  
        </Grid.RowDefinitions>  
      
        <Button Grid.Column="0" Grid.Row="0" Content=" 0  , 0"></Button>  
        <Button Grid.Column="1" Grid.Row="1" Content=" 1  , 1"></Button>  
        <Button Grid.Column="2" Grid.Row="2" Content=" 2  , 2"></Button>  
    </Grid>
    

      在该示例中,我们将Grid控件分为3行2列,而添加Button时我们却设定其位置分别为(0,0),(1,1),(2,2)。很明显,该Grid并不包含(2,2)–因为它只有2列,但是调试运行时系统并不会报错,而是出现下面的结果:
    在这里插入图片描述
      wpf中 <ColumnDefinition Width="82*"/>* 号表示什么,82* 又是什么意思?代表对比值,但并不代表82%,单独一个是没意义的,它是需要有对比才有意义的。
      如一行中有两列:

    <ColumnDefinition Width="1*"/>
    <ColumnDefinition Width="2*"/>
    

      则代表第一列占1/3,而第二列则占2/3;如果直接写*,而前面不带数字,则代表占用剩余所有空间。

    九 Binding(数据绑定)的用法

      本节内容来自这里
      1、Data Binding作用:Data Binding在WPF系统中起到数据高速公路的作用,有了这条高速公路,加工好的数据会自动送达到用户界面加以显示,被用户修改过的数据也会自动回传逻辑层。
      数据绑定就是将数据和图形用户界面(GUI)上的控件元素关联起来,起到用户可以通过用户界面上的控件元素对数据进行操作的目的。传统的数据绑定是后台代码与GUI的控件元素属性进行交互,使用功能数据绑定减少了代码量。
      2、组成:WPF中的绑定完成了绑定源和绑定目标的联动。一个绑定常常由四部分组成:绑定源、路径、绑定目标及目标属性,同时转换器也是一个非常重要的组成。
      3、Binding的源
      Binding的源就是数据的源头,数据的源头只要是一个对象,并且通过属性公开自己的数据,即可作为Binding的源。
      4、Binding的源总结:

    • 把普通CLR类型单个对象指定为Source。包括.NET Framework自带类型的对象和用户自定义类型的对象。
    • 把普通CLR集合类型对象指定为Source。包括数组、List、ObservableCollection等集合类型。
    • 把ADO.NET数据对象指定为Source。包括DataTable和DataView对象。
      把依赖对象指定为Source。
    • 把容器DataContext指定为Source。

      5、把控件作为 Binding 源与 Binding 标记扩展

    <Window x:Class="testBinding2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <StackPanel>
                <TextBox x:Name="textBox1" Text="{Binding Path=Value,ElementName=slider1}"/>
                <Slider x:Name="slider1" Maximum="100" Minimum="0"/>
            </StackPanel>   
        </Grid>
    </Window>
    

    使用Binding标记扩展语法,等价于C#

    this.textBox.SetBinding(TextBox.TextProperty,new Binding(“Value”){ ElementName=“slider1”});
    2)使用集合对象作为列表控件的ItemsSource

     WPF中列表式控件派生自ItemsControl类,自然继承了ItemsSource属性,这个属性可以接收一个IEnumerable接口派生类的实例作为自己的值。注意:使用集合类型作为列表控件的ItemsSource时一般考虑使用ObservableCollection<T>代替List<T>,因为ObservableCollection<T>类继承实现了INotifyCollectionChanged和INotifyPropertyChanged接口,能把集合的变化立即通知显示它的列表控件,改变会立即显示出来。
    

    应用举例:

    前台代码:

    <Window x:Class="testBinding2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <StackPanel>
                <TextBlock Text="Student ID:"  FontWeight="Bold" Margin="5" />
                <TextBox x:Name="textBoxId" Margin="5"/>
                <TextBlock Text="Student List:" FontWeight="Bold" Margin="5"/>
                <ListBox x:Name="listBoxStudents" Height="180" Margin="5"/>
                    <!--<ListBox.ItemTemplate>
                    </ListBox.ItemTemplate>-->
            </StackPanel>   
        </Grid>
    </Window>
    

    后台代码:

    namespace testBinding2
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                List<Student> stuList = new List<Student>()
                {
                    new Student() { Id = 0, Name = "Tim", Age = 29 },
                    new Student() { Id = 1, Name = "Tom", Age = 28 },
                    new Student() { Id = 2, Name = "Kyle", Age = 27 },
                    new Student() { Id = 3, Name = "Tony", Age = 24 },
                    new Student() { Id = 4, Name = "Vina", Age = 23 },
                    new Student() { Id = 5, Name = "Mike", Age = 22 },
                };
                //为ListBox设置Binding
                this.listBoxStudents.ItemsSource = stuList;//数据源
                this.listBoxStudents.DisplayMemberPath = "Name";//路径
                //为TextBox设置Binding
                Binding binding = new Binding("SelectedItem.Id") { Source=this.listBoxStudents};
                this.textBoxId.SetBinding(TextBox.TextProperty,binding);
            }
        }
        //创建一个名为Student的类,它具有Id、Name、Age三个属性
        public class Student
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
        }
    }
    

    效果:
    2)Binding 的数据流方向(绑定的模式)
    默认情况下,数据既能通过Binding送达目标,也能够从目标返回源。控制Binding数据流向的属性是Mode,它的类型是BindingMode,枚举为 TowWay ,OneWay,OnTime、OneWayToSource和Default。
    OneWay(常规数据流):数据来源是一个数据集合,目标是一个控件元素。
    TowWay:数据来源和目标任意发生改变时都更新数据来源和目标。
    (2)Binding 的路径
    Binding 的Path属性指定Binding源的对象哪个属性。如上所示 Slinder控件对象当做源,把它的Value属性作为路径。
    特殊:没有Path的Binding ,即Binding源的本身就是数据。
    二、应用
    点击button按钮时TextBox控件的内容改变
    1、界面设计

    <Window x:Class="testBinding.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <StackPanel>
                <TextBox x:Name="textBoxName" BorderBrush="Black" Margin="5" />
                <Button Content="Add Age" Margin="5" Click="Button_Click"/>
            </StackPanel>
        </Grid>
    </Window>
    

    2、后台设计

    using System.ComponentModel;
     
    namespace testBinding
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            Student stu;
            public MainWindow()
            {
                InitializeComponent();
     
                //准备数据源       
                stu = new Student();
                //准备Binding
                Binding binding = new Binding();//创建Binding实例
                binding.Source = stu;//指定数据源
                binding.Path = new PropertyPath("Name");//指定访问路径 
     
                //使用Binding 连接数据源与Bingding目标
                BindingOperations.SetBinding(this.textBoxName,TextBox.TextProperty,binding);//使用binding实例将数据源与目标关联起来
                //参数为 目标;目标的某个属性
            }
     
            private void Button_Click(object sender, RoutedEventArgs e)
            {
               stu.Name+="Name11";
            }
        }
     
        class Student:INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private string name;
     
            public string Name
            {
                get { return name; }
                set
                {
                    name = value;
                    if(this.PropertyChanged!=null)
                    {
                        this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));//当Name的属性值发生改变时,PropertyChanged事件触发
                    }
                }
            }        
        }
    }
    

    十 图像控件

      本节内容来自这里
      图像的放大效果显示平滑,如果要显示到像素点,则需要:
      xaml代码如下:

     <Image  Name="Img" RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.ClearTypeHint="Enabled" ></Image>
    

      后台代码为:

    RenderOptions.SetBitmapScalingMode(Img,BitmapScalingMode.NearestNeighbor);
    RenderOptions.SetClearTypeHint(Img,ClearTypeHint.Enabled);
    

    十一 loaded 事件和 Initialized 事件

      本节内容来自这里
      在 WPF 中,控件有 Loaded 和 Initialized 两种事件. 初始化和加载控件几乎同时发生, 因此这两个事件也几乎同时触发. 但是他们之间有微妙且重要的区别. 这些区别很容易让人误解. 这里介绍我们设计这些事件的背景. (不仅适用于 Control 类, 同样在通用类如 FrameworkElement 和 FrameworkContentElement 类也适用.)
      下面是个小故事:

    • Initialized 事件只说: 这个元素已经被构建出来,并且它的属性值都被设置好了,所以通常都是子元素先于父元素触发这个事件.当一个元素的 Initialized 事件被触发, 通常它的子树都已经初始化完成, 但是父元素还未初始化. 这个事件通常是在子树的 Xaml 被加载进来后触发的. 这个事件与 IsInitialized 属性相互绑定.
    • Loaded 事件说: 这个元素不仅被构造并初始化完成,布局也运行完毕,数据也绑上来了,它现在连到了渲染面上(rendering surface),秒秒钟就要被渲染的节奏.到这个时候,就可以通过 Loaded 事件从根元素开始画出整棵树. 这个事件与 IsLoaded 属性绑定.
      如果你不确定该用哪个事件, 而且也不想继续读下去, 那就用 Loaded 事件好了, 通常它都是对的.
      然后, 就是整个故事了.

      Initialized 事件
      这个事件在所有子元素都被设置完成时触发. 具体来说, FrameworkElement/FrameworkContentElement 实现了 ISupportInitialize 接口, 当该接口的 EndInit 方法调用时, IsInitialized 值被设置为 true. 事件就被触发了.
      ISupportInitialize 在 WPF 之前就存在了. 有这个接口, 你就可以在设置 control 的某个属性时,提前告知它你要开始执行一个批处理,之后再告诉它你已经做完了.这样实现了这个接口的对象就可以推迟它的属性值修改事件的处理直到 EndInit 被调用. 在 WPF 中, 不只是 element 用这个接口来触发 Initialized 事件, 其他对象如 DataSourceProvider 也实现这个接口.
      槽点是, 到底什么时候调用 EndInit 方法? 起点在 Xaml 加载器.(如果你懂 Baml 的话, 这个方法 Baml 加载器也会调用.) Xaml 加载器在构造对象时就调用 BeginInit. (也就是看见了起始标签), 然后在结束标签那里调用 EndInit 方法. 例子如下:

    <Button Width="100">
      Hello
    </Button>
    

      …创建一个 Button 对象, 调用 BeginInit, 设置宽度属性, 设置内容属性, 调用 EndInit 方法.
      如果用代码来构建元素, 你也可以自己调用 BeginInit/EndInit 方法. 有个问题就是, 不用 Xaml 构造, 也不自己调用 EndInit 方法, 那初始化事件还能触发吗? 答案必须是 yes. 所以我们提供了一些别的方式来设置 IsInitialized 值, 触发事件.

    • 当一个未初始化的元素被加到可视化树中时, 初始化事件被触发. 这个方法对于所有的非根元素都有效. 至于根元素, 所有的根元素都是从 PresentationSource 中来的, 所以你懂的…
    • 当一个未初始化元素被加入到 PresentationSource 中的时候, 初始化事件会被近似的触发.

      从 Initialized 事件的定义中, 可以看出, 这个事件必定是由下向上触发的, 也就是说父元素不应该被初始化直到子元素被初始化完成. 所以通常情况下都是子元素先于父元素被初始化. 不过这一点无法保证, 因为任何人都有可能调用 ISupportInitialize. 从 Xaml 中加载元素的话, 这点倒是可以保证.
      另一个槽点是, 元素要这个事件干嘛用? 元素无法获取别处定义的 styles 直到初始化事件触发. 例如 Button1 会从这个 style 中获取一个蓝色的背景. 但是在初始化事件之前, 这个背景是null.

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" >
      <Page.Resources>
        <Style TargetType="Button">
          <Setter Property="Background" Value="Blue" />
        </Style>
      </Page.Resources>
     
      <Button Name="Button1">Clack</Button>
    </Page>
    

    Loaded 事件
    Loaded 事件在元素即将要被渲染时触发. 设计这个事件是考虑你可能需要在程序加载期间做一些初始化操作.

    用 Initialized 事件也可以满足这个要求, 因为这个事件意味着元素已经被构建出来, 而且它的元素值也被设置过. 但这个事件还是少了点东西. 举个例子, 你可能需要知道一个元素的 AcutualWidth 属性值, 但是初始化事件触发时, 实际宽度还没有计算出来. 或者你想要看数据绑定的值, 这个值一样也还没有设定.

    所以, 我们提供了 Loaded 事件. 它可以在窗口渲染完成, 但是还没有执行任何交互时触发. 我们原本以为控件在可以接受输入的时候做加载是初始化操作就够了. 但是当我们开始在加载事件中触发动画时, 我们发现了一个问题. 有那么一小会, 你会发现元素内容在渲染时没有动画效果, 过后你才会看到动画效果. 你可能没有发现这个问题, 但是这个问题在远程运行程序时会很明显.

    所以我们移动了这个事件, 保证在这个事件之前数据绑定和布局有充足的事件执行,同时保证在第一次渲染前触发.(注意如果你要在加载事件中做任何使布局失效的操作, 那一定要记得在渲染前重新运行下布局. )

    因为整棵元素数在同一时间走到 Loaded 事件,这个事件会在整棵树内广播. 广播从根元素开始, 所以加载事件是从父元素到子元素.

    属性是鸡, 事件是蛋.

    另一个槽点是, 到底是先改了属性值,然后触发了事件, 还是先触发事件再改属性值.(一般人都知道答案吧, 作者在卖萌.)

    在 WPF 中, 如果有一个属性以及一个和该属性相关的事件, 通常都是修改该属性值来触发该事件. 例如对于 ListBox, 总是修改 SelectedItem 属性值, 触发了SelectionChanged 事件, Loaded 和 Initialized 事件也遵循这个模式.

    对于 Loaded 事件有点特殊, 在任何元素的 Loaded 事件触发前, IsLoade 属性在整棵元素树中被设置. 也就是说, 元素树内的所有元素的 IsLoaded 值被设置为 true 之后, 所有元素的 Loaded 事件才被触发.

    现在回过头来看上面 Page 中 的 Button 的例子,从 Xaml 文件中加载这个page, 你应当会看到以下的执行顺序.

    Button.IsInitialized goes true
    Button.Initialized event is raised
    Page.IsInitialized goes true
    Page.Initialized event is raised
    Page IsLoaded goes to true
    Button IsLoaded goes to true
    Page.Loaded is raised
    Button.Loaded is raised

    十二 pdf显示:MoonPdfLib

      本节内容来自这里

    十三 资源字典ResourceDictionary使用

      本节内容来自这里
      资源字典的意义在于:
      1.高效,可以通过资源定义对象,并在标记的多个地方使用,这会精简代码
      2.可维护性,通过资源使用低级的格式化细节,如字号,并将它们移到便于修改的中央位置。在XAML中创建资源相当于在代码中创建常亮
      3.适应性,一旦某些特定信息与应用程序的其他部分分离开来,并放在资源中,那么可以动态的修改这些信息,如修改皮肤或者语言

    资源字典的使用分为三步:

    1.新建资源字典

    新建的如下:

    <ResourceDictionary xmlns=“http://schemas.microsoft.com/winfx/2006/xaml/presentation”

    xmlns:x=“http://schemas.microsoft.com/winfx/2006/xaml”>

    2.新建一些资源,如string,double,color,SolidColorBrush

    <sys:String x:Key=“key001”>资源字典string</sys:String>

    #FF3232

    在 System空间下,可以使用xmlns:sys=“clr-namespace:System;assembly=mscorlib”> 来引入命名空间,就跟using一样

    3.绑定资源字典
    有代码和xaml两种方式

    代码:

    public static void loadRd()
            {
                var brushes_rd = new ResourceDictionary()
                {
                    Source = new Uri("pack://Application:,,,/testXml;component/dictionary.xaml")
                };
                Application.Current.Resources = new ResourceDictionary()
                {
                    MergedDictionaries =
                    {
                        brushes_rd
                    }
                };
            }
    

    Appllication 使用上面的 MergedDictionaries,可以添加多个资源字典

    或者直接:

    this.Resources= new ResourceDictionary()
    { 
        Source = new Uri("pack://Application:,,,/testXml;component/dictionary.xaml")
    };
    

    在基本控件中都有resources这个属性,而且查询资源的时候,会先从本控件开始找,然后一层层向上,最后会到达application的资源,若还是找不到则会查到系统本地的资源
    使用XAML的方式,一般都是在app.xml下绑定,如:

    <Application x:Class="WpfApp2.App"
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    	xmlns:local="clr-namespace:WpfApp2" 
    	StartupUri="MainWindow.xaml"> 
    		<Application.Resources> 
    			<ResourceDictionary> 
    				<ResourceDictionary.MergedDictionaries> 
    				<ResourceDictionary Source="Test.xaml"/> 
    				</ResourceDictionary.MergedDictionaries> 
    			</ResourceDictionary> 
    		</Application.Resources> 
    </Application>
    

    4.使用资源
    使用也分xaml和代码两种:

    xaml如下:

     <Button Margin="121,30,107,230" Click="Button_Click"  Background="{StaticResource solidBrush001}">
    

    代码则可以用:

    Public MainWindow()
    {
        InitializeComponent();   
        //使用资源里的字符串
        MessageBox.Show(this.FindResource("key001") .ToString()); 
        //使用资源中的solidBrush
        this.Background=(SolidColorBrush)this.FindResource("solidBrush001");    
        //使用setResourceReference绑定,可以动态修改,如果dictionary发生改变,界面也随之改变
        this.SetResourceReference(BackgroundProperty,”solidBrush002”);       
        //设置如DrawingImage资源
        var  drawing=(DrawingImage)this.FindResource("DrawingImageKey001");
    	Image  image=new Image{Source = t};
    	button.Content=drawing;
    }
    

    一般是使用FindResource 或者 用SetResourceReference来进行使用
    总结下使用资源字典的步骤:
    1.新建并添加资源
    2.绑定资源字典,有代码和xaml两种方式
    3.使用字典,有代码和xaml两种方式

    十四 wpf thumb

    1 事件

    Thumb类,表示可由用户拖动的控件。其主要三个事件分别DragDelta,DragStarted,DragCompleted.
    DragDelta——当 Thumb 控件具有逻辑焦点和鼠标捕获时,随着鼠标位置更改发生一次或多次。
    DragStarted——在 Thumb 控件接收逻辑焦点和鼠标捕获时发生。
    DragCompleted——在 Thumb 控件失去鼠标捕获时发生。

    <Window.Resources>
       <ResourceDictionary>
         <ControlTemplate x:Key="template1">
             <Ellipse Width="60" Height="30">
                 <Ellipse.Fill>
                     <SolidColorBrush Color="Black"></SolidColorBrush>
                 </Ellipse.Fill>
             </Ellipse>
         </ControlTemplate>
       </ResourceDictionary>
    </Window.Resources>
      
    <Canvas Name="myCanvas">
      <Thumb Name="myThumb" DragDelta="onDragDelta" Background="Blue"  DragStarted="myThumb_DragStarted" DragCompleted="myThumb_DragCompleted"
             Canvas.Left="0" Canvas.Top="0"  Width="200" Height="200"/>
          <!--Template="{StaticResource template1}",若此处采用此种方法为Thumb绑定模版,是无法通过DragStarted,DragCompleted事件来改变其背景的-->
    </Canvas>
    
    void onDragDelta(object sender, DragDeltaEventArgs e)
    {
    	Canvas.SetLeft(myThumb, Canvas.GetLeft(myThumb) + e.HorizontalChange);							   
    	Canvas.SetTop(myThumb, Canvas.GetTop(myThumb) +  e.VerticalChange);							  
    }
    
    private void myThumb_DragStarted(object sender, DragStartedEventArgs e)
    {
    	myThumb.Background = Brushes.Orange;
    }
    
    private void myThumb_DragCompleted(object sender, DragCompletedEventArgs e)
    {
    	myThumb.Background = Brushes.Blue;
    }
    

    2 示例

      本节内容来自这里

    十五 弹出子页面

      wpf中子窗口的几个问题:https://www.cnblogs.com/hyper-xl/p/5419374.html
      C# Note18: 使用wpf制作about dialog(关于对话框):https://www.cnblogs.com/carsonzhu/p/7340699.html

    十六 wpf 界面切换

      界面切换和窗口跳转是所有桌面程序都需要的。 wpf里面也有很多方法来做到界面切换,简单常用的有TabControl和UserControl。

    1 TabControl

      优点是简单,继续拖控件;缺点就是全部代码会堆到一起。

    <TabControl HorizontalAlignment="Left" Height="200" Margin="10,10,0,0" VerticalAlignment="Top" Width="500">
        <TabItem Header="TabItem1">
            <Grid Background="#FFE5E5E5"/>
        </TabItem>
        <TabItem Header="TabItem2">
            <Grid Background="#FFE5E5E5"/>
        </TabItem>
    </TabControl>
    

      把控件拖进去就好了。

    2 ContentControl

      本节内容来自这里
      这里推荐使用 UserControl,把需要的界面组合成一个控件,配合 Frame 或者 ContentControl 来切换界面。
      创建一个 UserControl,右键项目点击添加新建项,选择用户控件:
    在这里插入图片描述
      然后就是创建你想要的界面了,这样代码就分离了出来,以后也可以复用。
      推荐使用ContentControl来加载。

    ControlControl1.Content = new UserControl1();
    

      这样自定义的控件就会加载了。不得不说wpf真的很灵活。

    十七 Canvas

    1 WPF中获取Canvas中控件的坐标方法

    1.获取控件坐标方法:
    Canvas.GetTop(Button);Canvas.GetLeft(Button)。
    2.设置坐标方法:
    Canvas.SetLeft(Button,坐标值);Canvas.SetTop(Button, 坐标值)。

    2 在WPF中的Canvas上实现控件的拖动、缩放

      本节内容来自这里

    十八 程序打包

      :https://blog.csdn.net/cupid_1314/article/details/79364340
      :https://www.cnblogs.com/wuhuacong/p/6101853.html
      :https://www.cnblogs.com/yayx/archive/2008/04/22/1166064.html

    十九 WPF事件

      本节内容来自这里
    1:什么是路由事件
      WPF中的事件为路由事件,所谓路由事件,MSDN定义如下:
      功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。
      实现定义:路由事件是一个 CLR 事件,可以由 RoutedEvent 类的实例提供支持并由 Windows Presentation Foundation (WPF) 事件系统来处理。
    但这两类定义都比较抽象,我们来看更具体的定义:

    <Border Height="50" Width="250" BorderBrush="Gray" BorderThickness="1" >
      <StackPanel Background="LightGray" Orientation="Horizontal" MouseUp="StackPanel_MouseUp">
          <TextBlock Name="YesTB" Width="50"  MouseUp="YesTB_MouseUp" Background="Blue" >Yes</TextBlock>
       </StackPanel>
    </Border>
    

      在这个例子中,事件的事件路由为:TextBlock -->StackPanel-->Border —>...
    2:中断事件路由
      所有的路由事件都共享一个公共的事件数据基类 RoutedEventArgs。RoutedEventArgs 定义了一个采用布尔值的 Handled 属性。Handled 属性的目的在于,允许路由中的任何事件处理程序通过将 Handled 的值设置为 true 来将路由事件标记为“已处理”。

    private void StackPanel_MouseUp(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("Panel");
    }
    
    private void YesTB_MouseUp(object sender, MouseButtonEventArgs e)
    {
        MessageBox.Show("button");
        e.Handled = true;
    }
    

      在上面的例子中,将不再触发StackPanel_MouseUp事件。
    3:自定义路由事件
      如下面的示例所示,首先使用 RegisterRoutedEvent 方法注册一个 RoutedEvent。按照约定,RoutedEvent 静态字段名称应当以后缀 Event 结束。在本示例中,事件的名称是 Tap,事件的路由策略是 Bubble。在注册调用之后,可以为该事件提供添加和移除公共语言运行时 (CLR) 事件访问器。
    请注意,尽管该事件在本特定示例中是通过 OnTap 虚方法引发的,但您引发事件的方式或者事件响应更改的方式取决于您的需要。
      还要注意,本示例主要实现 Button 的一整个子类;该子类是作为单独的程序集构建的,之后将在单独的可扩展应用程序标记语言 (XAML) 页上实例化为一个自定义类。这是为了说明这样一个概念:创建子类的控件可以插入到由其他控件组成的树中,在这种情况下,这些控件上的自定义事件具有与任何固有的 Windows Presentation Foundation (WPF) 元素完全相同的事件路由功能。

    public class MyButtonSimple: Button
    {
        // Create a custom routed event by first registering a RoutedEventID
        // This event uses the bubbling routing strategy
        public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
            "Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));
    
        // Provide CLR accessors for the event
        public event RoutedEventHandler Tap
        {
                add { AddHandler(TapEvent, value); } 
                remove { RemoveHandler(TapEvent, value); }
        }
    
        // This method raises the Tap event
        void RaiseTapEvent()
        {
                RoutedEventArgs newEventArgs = new RoutedEventArgs(MyButtonSimple.TapEvent);
                RaiseEvent(newEventArgs);
        }
        // For demonstration purposes we raise the event when the MyButtonSimple is clicked
        protected override void OnClick()
        {
            RaiseTapEvent();
        }
    
    }
    
    <Window  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary"
        x:Class="SDKSample.RoutedEventCustomApp"
    
        >
        <Window.Resources>
          <Style TargetType="{x:Type custom:MyButtonSimple}">
            <Setter Property="Height" Value="20"/>
            <Setter Property="Width" Value="250"/>
            <Setter Property="HorizontalAlignment" Value="Left"/>
            <Setter Property="Background" Value="#808080"/>
          </Style>
        </Window.Resources>
        <StackPanel Background="LightGray">
            <custom:MyButtonSimple Name="mybtnsimple" Tap="TapHandler">Click to see Tap custom event work</custom:MyButtonSimple>
        </StackPanel>
    </Window>
    

    4:为什么需要自定义路由事件
      一直到目前看来,我们都不太需要自定义的路由事件。但是,在我们创建自定义控制的时候,创建一些和业务相关的路由事件,就显得很有必要。
      如,创建一个在线考试中的题型展示控件,可以为该控件设计一个自定义事件,为“提交”。这样一来,这个题型控件不仅仅只有一些通用事件,还可以看上去更“业务”。
    5:什么是冒泡事件和预览事件(隧道事件)
      路由事件实际上分两类:冒泡事件和预览事件(隧道事件)。上文中的例子就是冒泡事件。
      冒泡事件是WPF路由事件中最为常见,它表示事件从源元素扩散(传播)到可视树,直到它被处理或到达根元素。这样您就可以针对源元素的上方层级对象处理事件。例如,您可向嵌入的 Grid 元素附加一个 Button.Click 处理程序,而不是直接将其附加到按钮本身。气泡事件有指示其操作的名称(例如,MouseDown)。
      隧道事件采用另一种方式,从根元素开始,向下遍历元素树,直到被处理或到达事件的源元素。这样上游元素就可以在事件到达源元素之前先行截取并进行处理。根据命名惯例,隧道事件带有前缀 Preview(例如 PreviewMouseDown)。
      在本文一开始的例子中,如果我们将 MouseUP,改为 PreviewMouseUP,效果会如何呢。
      区别:
      冒泡事件:在 YesTB 上点击,首先弹出“button”,再弹出“panel”。
      预览事件(隧道事件)事件:在 YesTB 上点击,首先弹出“panel”,再弹出“button”。
      看到了这点区别,那么我们加入 e.Handled=true 的时机也要不同。首先,
    冒泡事件例子中:e.Handled=true 加在 YesTB_PreviewMouseUp 中,加入后,点击 YesTB,将只弹出“button”。
      预览事件(隧道事件)例子中:e.Handled=true 家在 StackPanel_PreviewMouseUp 中,加入后,点击 YesTB,将只弹出“panel”。

    展开全文
  • 获取桌面应用程序

    2015-11-26 16:50:07
    获取桌面的应用程序信息,并展示出来,包括多个图标和名称的。博客地址:http://blog.csdn.net/harryweasley/article/details/50057029
  • 前段时间又做了点简单的桌面程序,时间长了也忘记以前打包的部署了,现在以免忘记,也便于和大家分享一下把主要的过程,大概的写一下,但愿以后疏忽了可以查看一下! 1.下面选择工程类型,选jar  2.输入程序名称...



     当初学习和开发java桌面应用程序几乎都在jbulider上,现在也移植到了netbean上了!但最终需要发布给客户!前段时间又做了点简单的桌面程序,时间长了也忘记以前打包的部署了,现在以免忘记,也便于和大家分享一下把主要的过程,大概的写一下,但愿以后疏忽了可以查看一下!

    1.下面选择工程类型,选jar



     2.输入程序名称没有限制,然后next

     3.输入你想要的exe文件名称如:laoge,然后选择一个ico作为程序的标准,然后next

     4.这一步先要选择下面的“+”选择jar包,之火main class中自动添加你想要的main函数,只需要选择就可以了!其他的不用填写也可以,然后next

     5.现在要选择自己的jre了,应为客户端不可能按照jre,所以要自己添加jre来运行程序了,输入jre版本,然后选择下拉菜单,见下图

     6.选择serach sequce

     7.这一步要删除原来的默认系统路径,只留下这一个serach。。。就可以了然后选择右边的选择按钮

     8.然后选择你的jre包 就可以了 剩下的不用填写也可以,直接falish就行了,然后发现桌面有个你想要的标志!点击就ok了

     
    值得注意的是exe4j需要添加注册吗!否则点击.exe文件后会先弹出一个讨厌的框,提示你exe4j没有注册!
     

    展开全文
  • :package: pySteal-Minecraft.exe- 非常简单和愚蠢的窃取程序,它从桌面窃取名称为“ Password.txt”的文件。
  • 做一个WPF程序用于计算两个数之和,用UIAutomation测试输入两个数字,后WPF计算的程序是否为预期的数字。 创建一个名称为WPFUIAutomation的WPF项目,在MainWindows.xaml的窗体中做如下布局及后台代码。 <Window...

    人狠话不多~!

    • 做一个WPF程序用于计算两个数之和,用UIAutomation测试输入两个数字,后WPF计算的程序是否为预期的数字。
    • 创建一个名称为WPFUIAutomation的WPF项目,在MainWindows.xaml的窗体中做如下布局及后台代码。
    <Window x:Class="WPFUIAutomation.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WPFUIAutomation"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
            <TextBox x:Name="tbNo1" Height="30" Width="50" Margin="10"/>
            <TextBlock Text="+"/>
            <TextBox x:Name="tbNo2" Height="30" Width="50" Margin="10"/>
            <TextBlock Text="="/>
            <TextBox x:Name="tbNo3" Height="30" Width="50" Margin="10"/>
            <Button x:Name="btnSum" Click="BtnSum_OnClick" Height="30" Width="50" Content="计算"/>
        </StackPanel>
    </Window>
    

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WPFUIAutomation
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void BtnSum_OnClick(object sender, RoutedEventArgs e)
            {
                int i = int.Parse(tbNo1.Text);
                int j = int.Parse(tbNo2.Text);
    
                tbNo3.Text = (i + j).ToString();
            }
        }
    }
    
    • 创建名称为WPFUIAutomationConsole的控制台项目,引入UIAutomationClient.dll、UIAutomationClientsideProviders.dll、UIAutomationProvider.dll、UIAutomationTypes.dll
    • 将WPFUIAutomation的输出路径修改为WPFUIAutomationConsole的bin目录下。WPFUIAutomationConsole的代码如下。
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using AppDomain = System.AppDomain;
    using System.Windows.Automation;
    
    namespace WPFUIAutomationConsole
    {
        class Program
        {
            static void Main(string[] args)
            {
                //获取exe程序
                string path = AppDomain.CurrentDomain.BaseDirectory + "WPFUIAutomation.exe";
                //运行exe程序
                Process p = Process.Start(path);
                //自动化根元素
                AutomationElement aeRoot=AutomationElement.RootElement;
                //等待exe程序启动
                Thread.Sleep(2000);
                //获取主窗体
                AutomationElement aeFrom=AutomationElement.FromHandle(p.MainWindowHandle);
                //等待计数
                int waitIndex = 0;
                //获得主窗体对象的引用
                do
                {
                    Console.WriteLine("第{0}查找主窗体", waitIndex);
                    //查找第一个自动化元素
                    aeFrom = aeRoot.FindFirst(TreeScope.Children,
                        new PropertyCondition(AutomationElement.NameProperty, "MainWindow"));
    
                } while (aeFrom==null && waitIndex<50);
                //没有获取到主窗体
                if (aeFrom==null)
                {
                    throw new NullReferenceException("未找到窗体。");
                }
                else
                {
                    Console.WriteLine("找到窗体。");
                }
                //Name为btnSum的控件
                AutomationElement aeButton = aeFrom.FindFirst(TreeScope.Children,
                    new PropertyCondition(AutomationElement.AutomationIdProperty, "btnSum"));
                //Name为tbNo1的TextBox控件
                AutomationElement aeTextBo1 = aeFrom.FindFirst(TreeScope.Children,
                    new PropertyCondition(AutomationElement.AutomationIdProperty, "tbNo1"));
                //Name为tbNo2的TextBox控件
                AutomationElement aeTextBo2 = aeFrom.FindFirst(TreeScope.Children,
                    new PropertyCondition(AutomationElement.AutomationIdProperty, "tbNo2"));
                //Name为tbNo3的TextBox控件
                AutomationElement aeTextBo3 = aeFrom.FindFirst(TreeScope.Children,
                    new PropertyCondition(AutomationElement.AutomationIdProperty, "tbNo3"));
                //设置第一个TextBox的值为25
                ValuePattern vp1 = (ValuePattern) aeTextBo1.GetCurrentPattern(ValuePattern.Pattern);
                vp1.SetValue("25");
                //设置第二个TextBox的值为25
                ValuePattern vp2 = (ValuePattern)aeTextBo2.GetCurrentPattern(ValuePattern.Pattern);
                vp2.SetValue("25");
                //让子弹飞一会
                Thread.Sleep(1500);
                //通过InvokePattern,实现模拟点击按钮
                InvokePattern clickButton = (InvokePattern) aeButton.GetCurrentPattern(InvokePattern.Pattern);
                clickButton.Invoke();
                //让子弹飞一会
                Thread.Sleep(1500);
                //获取第三个TextBox的值
                ValuePattern vp3 = (ValuePattern)aeTextBo3.GetCurrentPattern(ValuePattern.Pattern);
                string result = vp3.Current.Value;
    
                //判断是否为预期的60
                if (result.Equals("60"))
                {
                    Console.WriteLine("验证通过。");
                }
                else
                {
                    Console.WriteLine("验证失败,测试结果为{0}。", result);
                }
    
                Thread.Sleep(3000);
                //关闭被测试程序
                WindowPattern closeForm = (WindowPattern) aeFrom.GetCurrentPattern(WindowPattern.Pattern);
                closeForm.Close();
    
                Console.WriteLine("测试程序已关闭。");
                Console.ReadLine();
            }
        }
    }
    

     

    展开全文
  • 1-6第一个桌面程序

    2020-10-10 17:00:58
    1-6第一个桌面程序 菜单栏文件 —> 新建 —> 项目 —> WPF应用程序 更改一下名称和位置 点击确定,生成一个MainWindow.xaml文件和一个MainWindow.xaml.cs文件 在MainWindow.xaml.cs文件有这样一句话==...
  • Web和桌面应用程序,您可以在其中通过使用香草Javascript并以Bootstrap样式设置的名称搜索城市的天气。 :laptop: 电脑检视 :mobile_phone: 流动检视 :unlocked: 特征: 您可以实时查看城市的天气。 最后搜索的...
  • Visual Studio2017新建win32桌面程序

    万次阅读 热门讨论 2018-01-20 10:14:56
    1.新建->选择windows桌面向导2.选择windows应用程序exe如果是一开始学习可以将空项目选上3.在项目源文件上右键->添加->新建项选择cpp文件,然后修改文件名称,点击添加。4.之后添加如下源代码,调试即可#include ...
  • 桌面程序开发 — Log 重定向(输出到文件) 简述:在开发过程中,有时需要将开发程序的debug 信息写入文件中,以便调试查看。但是如果直接在文件中添加写文件的操作又比较繁琐,频繁的写文件也增加的程序的压力。下面...
  • java桌面程序源码下载 APKMessenger 软件介绍 APK Messenger 是一款电脑端APK信息文件提取工具,由果核剥壳网站开发,本软件为基于JAVA GUI开发的桌面程序 目前JAVA版本实现了功能 获取应用名,支持提取多语言名称 ...
  • 这是一个桌面带,用于显示当前虚拟桌面名称。 它基于的SharpShell和MScholtes的的出色项目。 功能 此deskband是示出当前虚拟桌面名称,并通过经由桌面快捷键CTRL + [1 - 9]实施的可能性开关。 安装 克隆存储库...
  • 桌面应用程序,在Windows,Mac和Linux上运行。 最初由大谷优弥(Yuya Ochiai)创建为“最电子的”。 用 。 产品特点 桌面整合 跨多个服务器的多个团队的选项卡 桌面通知 Windows 10:吐司 Windows 7-8.1:类似...
  • 使用平台构建的示例云和桌面应用程序的集合。 大纲 执照 概述 该存储库包含一组基于Theia的IDE应用程序(电子桌面应用程序和docker映像)作为示例,用于演示和持续集成。 Docker映像变体 图片名称 描述 文献资料...
  • 源码JSONExport,JSONExport是一款用Swift编写的桌面端应用程序,可以将任何有效的JSON对象转换为它所支持的语言的类。当你键入或者粘贴JSON时,JSONExport将会对所生成的内容进行预览,生成的内容包括构造函数、将...
  • 桌面1.0程序&源代码

    2009-07-07 15:26:24
    名称:酷桌面1.0程序&源代码 运行环境:.NET Framework 1.1 语言:C# 介绍:这里仿照酷桌面做的一个换桌面背景的程序 注意事项:因为桌面图片太大了,我就不上传了。请自行拷贝到LefsCool的image目录下或我的文档的...
  • 输入文件夹名称XXX,自动在桌面上新建一个文件夹XXX,然后将桌面上的文件的扩展名在XXX里新建子文件夹。再把相应到的文件移动到对应的子文件夹下,如doc文件都存入doc文件夹里。如果子文件夹里已经存在重名的文件,则...
  • 在IDE中创建可分发的应用程序,然后从IDE外部运行该应用程序。 1,在NetBeans IDE中,选择“文件”>“新建项目 2,在Choose Category页面中,选择Java类别中的Java 应用程序,然后单击Next。 3,在向导的...
  • 是否厌倦了在浏览器上搜索众多打开的选项卡才能查看您经常查看的网页? 使用 Nativefier 让事情变得更简单、更方便! Nativefier 是一个命令行工具,可以以最少的... 它将自动检索应用程序图标和名称,您可以覆盖它们。
  • 请根据相关需求说明及概要编码提示,结合桌面应用程序开发所学知识,顺利完成下述软件的开发工作: 软件需求及编码提示:  本窗体包含一个主窗体,窗体标题叫文件查看器。  窗体左上角放置一个载入按钮。  ...
  • 请利用所学的桌面应用开发知识,仿照完成一个类似测距仪功能的小软件,功能要求如下所示,最终效果见Demo文件夹: 软件需求及编码提示: 该软件只需要一个窗体,该窗体名称为FrmDistanceMeasure, 该窗体标题为...
  • Electron是由Github开发,用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库https://electronjs.org/docs vue init simulatedgreg/electron-vue 你的项目名称 根据提示安装 npm install 安装依赖如果...
  • 厌倦了仅在浏览器中浏览常规打开的网页时就不得不在浏览器中搜索众多打开的标签的麻烦? 借助Nativefier,让事情变得更轻松,更方便。 Nativefier是一个命令行工具,... 它将自动检索您可以覆盖的应用程序图标和名称
  • 桌面程序开发入门(WinForm with C#)

    千次阅读 2018-12-14 12:59:11
    1、使用Visual Studio 2013创建新项目 2、创建一个主窗体和4个子窗体 3、创建一个数据库、一个表、一个存储过程 ...第二步:创建4个子窗体,名称分别是formCommandProc.cs、formDataAdapterProc.cs、formXMLCr...
  • 可用于 Windows PC 桌面端软件更新并重启 自行替换 $ORIGIN_FILE$ 为需删除的旧文件名称,$DOWNLOAD_FILE$ 为下载的新文件名称。$NEW_FILE$ 为需要重命名的下载文件名称。 @echo off for /l %%a in (1,1,10) do ( ...
  • 介绍在本文中,将介绍如何将窗口的最小化、关闭、最大化按钮隐藏,你可以...2:默认情况下,新添加的窗口名称会是form1,我们可以进行调整,然后可以在窗口上添加一些组件,例如edit、label、button等,<ignore...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,233
精华内容 893
关键字:

桌面程序名称