当前位置: 首页 > news >正文

WPF程序编译(从命令行到Visual Studio)

  • 回过头,继续看看 WPF 程序

如何从仅使用代码过渡到使用XAML呢...

例子

程序文件

编译

(一)只包含代码

program.cs

直接命令行调用csc

(二)代码+未编译XAML

grid.xaml
program.cs

同上

(三)代码+编译的XAML

mywindow.xaml
program.cs

写个工程文件(project.wpf),直接调用msbuild

(四)代码+编译的XAML

app.xaml
mywindow.xaml
program.cs

同上

程序结构?

  • C# 程序 需要有一个static的 Main() 成员函数作为入口点
  • GUI 程序至少需要有一个窗口
  • GUI 程序一般有一个 Application 实例来管理所有窗口以及程序全局资源等等

例子一(只使用代码)

我想写一个带布局的窗口,使用Grid布局一个 按钮和一个文本框

using System;
using System.Windows;
using System.Windows.Controls;

namespace DbZhang800
{
    public class MyWindow : Window
    {
        private TextBox textEdit;
        private int clickCount;

        public MyWindow()
        {
            this.Width = 300;
            this.Height = 300;
            this.Title = "Grid Layout";

            Grid grid = new Grid();
            ColumnDefinition col1 = new ColumnDefinition();
            col1.Width = GridLength.Auto;
            ColumnDefinition col2 = new ColumnDefinition();
            col2.Width = new GridLength(1, GridUnitType.Star);
            grid.ColumnDefinitions.Add(col1);
            grid.ColumnDefinitions.Add(col2);

            this.Content = grid;

            Button button1 = new Button();
            button1.Content = "Say Hello!";
            button1.Click += new RoutedEventHandler(button1_Click);
            grid.Children.Add(button1);
            Grid.SetColumn(button1, 0);

            textEdit = new TextBox();
            grid.Children.Add(textEdit);
            Grid.SetColumn(textEdit, 1);

            this.clickCount = 0;
        }

        void button1_Click(object sender, RoutedEventArgs e)
        {
            textEdit.Text = string.Format("Hello WPF's Grid Layout! No.{0}", this.clickCount);
            this.clickCount ++;
        }
    }

    public class App:Application
    {
        public App()
        {
        }

        [STAThread]
        public static void Main()
        {
            App app = new App();

            app.Run(new MyWindow());
        }
    }
}

编译一下:

Csc.exe /lib:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0" /r:PresentationCore.dll /r:PresentationFramework.dll /r:System.Core.dll /r:System.Windows.Presentation.dll /r:WindowsBase.dll /target:exe Program.cs

其他似乎都好说,就是和布局有关系的代码,太让人难受了(似乎和Qt的代码完全没办法比,哈)

例子二(未编译的xaml)

如果使用将布局相关的代码剥离出来,会不会好一点?

类似于Qt中 .ui 文件的动态加载

  • grid.xaml

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Button Name="button1" Grid.Column="0">Say Hello!</Button>
    <TextBox Name="textEdit1" Grid.Column="1" xml:space="preserve" />
</Grid>
  • program.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.IO;

namespace DbZhang800
{
    public class MyWindow : Window
    {
        private TextBox textEdit;
        private int clickCount;

        public MyWindow()
        {
            this.Width = 300;
            this.Height = 300;
            this.Title = "Grid Layout";

            FileStream s = new FileStream("grid.xaml", FileMode.Open);
            DependencyObject root = (DependencyObject)XamlReader.Load(s);
            this.Content = root;

            Button button1 = (Button)LogicalTreeHelper.FindLogicalNode(root, "button1");
            button1.Click += new RoutedEventHandler(button1_Click);

            textEdit = (TextBox)LogicalTreeHelper.FindLogicalNode(root, "textEdit1");

            this.clickCount = 0;
        }

        void button1_Click(object sender, RoutedEventArgs e)
        {
            textEdit.Text = string.Format("Hello WPF's Grid Layout! No.{0}", this.clickCount);
            this.clickCount ++;
        }
    }

    public class App:Application
    {
        public App()
        {
        }

        [STAThread]
        public static void Main()
        {
            App app = new App();

            app.Run(new MyWindow());
        }
    }
}

编译命令和前面完全相同(此处略)。

在代码中,我们通过 XamlReader 来加载这个 xaml 文件,并生成一个 DependencyObject,然后借助LogicalTreeHelper 找到我们需要进行逻辑操作的节点。

由于Grid等都是FrameWorkElement的派生类,故还可以

            //DependencyObject root = (DependencyObject)XamlReader.Load(s);
            FrameworkElement root = (FrameworkElement)XamlReader.Load(s);
            this.Content = root;

            //Button button1 = (Button)LogicalTreeHelper.FindLogicalNode(root, "button1");
            Button button1 = (Button)root.FindName("button1");

例子三(编译的xaml)

WPF程序中,xaml一般要编译成后baml文件,然后嵌入到资源中,同时,自动生成一个partial类,来完成xmal中控件和类中field的连接。(网上提到较多是xamlc.exe负责完成该工作;但现在,这个工具程序应该不存在了,该为由msbuild内置的Task来完成)。

同样是前一个程序,现在整个MyWindow改由 xaml实现:

  • 界面文件: mywindow.xaml

<Window x:Class="DbZhang800.MyWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300" Title="Grid Layout">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Button Name="button1" Click="button1_Click" Grid.Column="0">Say Hello!</Button>
        <TextBox Name="textEdit" Grid.Column="1" xml:space="preserve" />
    </Grid>
</Window>
  • 逻辑 program.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace DbZhang800
{
    public partial class MyWindow : Window
    {
        private int clickCount;

        public MyWindow()
        {
            InitializeComponent();
            this.clickCount = 0;
        }

        void button1_Click(object sender, RoutedEventArgs e)
        {
            textEdit.Text = string.Format("Hello WPF's Grid Layout! No.{0}", this.clickCount);
            this.clickCount ++;
        }
    }

    public class App:Application
    {
        public App()
        {
        }

        [STAThread]
        public static void Main()
        {
            App app = new App();

            app.Run(new MyWindow());
        }
    }
}

恩,程序写完了,一共两个文件。可是在没有Visual Studio的情况下,如何编译它呢??

因为没有xamlc.exe 这种命令行工具,只能使用MSBuild了,这样需要有一个工程文件

  • project.wpf

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <AssemblyName>HelloWPF</AssemblyName>
        <OutputType>winexe</OutputType>
</PropertyGroup>
<ItemGroup>
    <Reference Include="System" />
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
    <Page Include="mywindow.xaml" />
    <Compile Include="program.cs" />
</ItemGroup>

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
</Project>

基本完工了了,运行

msbuild project.wpf

即可得到可执行程序 HelloWPF.exe

例子四(常规)

上一个例子和Visual Studio生成的工程很接近了,但是还有一点。VS生成的工程中,Application也需要一个xaml文件(似乎比较让人困惑)。

  • mywindow.xaml (和前一个例子一样,略过)
  • app.xaml

<Application x:Class="DbZhang800.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="MyWindow.xaml">
</Application>
  • program.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace DbZhang800
{
    public partial class MyWindow : Window
    {
        private int clickCount;

        public MyWindow()
        {
            InitializeComponent();
            this.clickCount = 0;
        }

        void button1_Click(object sender, RoutedEventArgs e)
        {
            textEdit.Text = string.Format("Hello WPF's Grid Layout! No.{0}", this.clickCount);
            this.clickCount ++;
        }
    }

    public partial class App:Application
    {
    }
}

要编译这个程序,需要将 app.xaml加入我们前面的工程文件

  • project.wpf

...
<ItemGroup>
    <ApplicationDefinition Include="app.xaml" />
    <Page Include="mywindow.xaml" />
    <Compile Include="program.cs" />
</ItemGroup>
...

对于普通的xaml,使用的是Page,对于程序xaml文件,使用的是ApplicationDefinition(这样,为其自动生成的那个app.g.cs文件中会包含 Main入口函数)

好了,现在运行

msbuild project.wpf

即可。

程序编译没问题了,但是,但是,这个xaml和界面没有什么关系,为什么要弄个这东西出来??

对于代码编写者来说,这个确实没什么必要,而且有时它自动生成的Main入口可能还不符合我们的口味。但是对于使用其他工具进行界面设计的人来说,它就变得很重要了,比如:用来存放程序所需要的资源文件等。

参考

  • LIVING WITHOUT APP.XAML (... AND STILL BEING ABLE TO USE BLEND!)

  • Building a WPF Application (WPF)

  • Code and Compiled XAML

  • Understanding In and Out of XAML in WPF

  • How to load BAML resources


相关文章:

  • Hibernate学习(1)- 初识
  • C#下.NET配置文件使用(一)
  • JS运行机制(进程与线程的区分)
  • C#下.NET配置文件使用(二)
  • MAC为Apache2服务器配置多个虚拟主机
  • WPF下的布局(Layout、Panel)小记
  • let 与 const 的用法
  • 从CT技术想到的软件测试
  • Linux CentOS7 VMware 文件和目录权限chmod、更改所有者和所属组chown、umask、隐藏权限lsattr/chattr...
  • Linux WebSphere DB2
  • c\c++ 基本知识
  • 设计模式——责任链模式
  • 【Android】 Eclipse : ERROR: Unknown option '--no-crunch'的解决办法
  • Kibana6.x.x源码分析--Error: $injector:nomod Module Unavailable
  • 【Android】 使用ADT16出现ImageView Warning:Missing content Description attribute on image
  • [译] 怎样写一个基础的编译器
  • Angular数据绑定机制
  • CEF与代理
  • CentOS从零开始部署Nodejs项目
  • es的写入过程
  • Java教程_软件开发基础
  • JS函数式编程 数组部分风格 ES6版
  • leetcode讲解--894. All Possible Full Binary Trees
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • springboot_database项目介绍
  • Terraform入门 - 3. 变更基础设施
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 警报:线上事故之CountDownLatch的威力
  • 前端工程化(Gulp、Webpack)-webpack
  • 深入浅出webpack学习(1)--核心概念
  • 学习Vue.js的五个小例子
  • - 转 Ext2.0 form使用实例
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #1014 : Trie树
  • #NOIP 2014#Day.2 T3 解方程
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (3)(3.5) 遥测无线电区域条例
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (原創) 物件導向與老子思想 (OO)
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • .form文件_SSM框架文件上传篇
  • .gitattributes 文件
  • .NET Reactor简单使用教程
  • @SuppressWarnings注解
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用
  • [ 数据结构 - C++] AVL树原理及实现
  • [Android]竖直滑动选择器WheelView的实现
  • [AX]AX2012开发新特性-禁止表或者表字段
  • [CSS]浮动