注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[chap01] The Application and the Window  

2017-01-19 09:33:47|  分类: gui_WPF |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
写过 win32 app 的人,都读过 Petzold 的《Programming Windows》。
:-) 其实 Petzold 还给 WPF 写过类似的书,只不过手机大潮来领,WPF 没那么流行,书也就随之沉寂。
本着把玩 WPF 之心,以及对 Petzold 的崇敬,让我们一起来读读《Applications = Code + Markup》。

简单的 HelloWorld (SayHello.cs)
-------------------------------------------------------
using System;
using System.Windows;

namespace Petzold.SayHello
{
    class SayHello
    {
        [STAThread]
        public static void Main()
        {
            Window win = new Window();
            win.Title = "Say Hello - 你好";
            win.Show();

            Application app = new Application();
            app.Run();
        }
    }
}
-------------------------------------------------------

对应的 SayHello.csproj
-------------------------------------------------------
<Project
  DefaultTargets="Build"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <OutputType>winexe</OutputType>
    <OutputPath>.\</OutputPath>
    <AssemblyName>SayHello</AssemblyName>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="SayHello.cs" />
    <Reference Include="System" />
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
  </ItemGroup>

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

编译 exe
msbuild.exe SayHello.csproj

清理
msbuild.exe SayHello.csproj /t:Clean

Application 是 singleton,多次 new Application() 会抛异常。

OO设计的核心,请认真搞懂继承关系。:-)
来看一下 Application 和 Window 的继承关系。
Object
  DispatcherObject (abstract)
    Application
    DependencyObject
      Visaul (abstract)
        UIElement
          FrameworkElement
            Control
              ContentControl
                Window

UIElement 定义了 mouse、keyboard 的事件。
来看看如果响应鼠标消息:

HandleAnEvent.cs
-------------------------------------------------------
using System;
using System.Windows;
using System.Windows.Input;

namespace Petzold.HandleAnEvent
{
    class HandleAnEvent
    {
        [STAThread]
        public static void Main()
        {
            Application app = new Application();

            Window win = new Window();
            win.Title = "Handle An Event";
            win.MouseDown += WindowOnMouseDown;

            app.Run(win);
        }

        static void WindowOnMouseDown(object sender, MouseButtonEventArgs args)
        {
            Window win = sender as Window;
            string message = string.Format("Window clicked with {0} button at point ({1})",
                args.ChangedButton, args.GetPosition(win));
            MessageBox.Show(message, win.Title);
        }
    }
}
-------------------------------------------------------

获得当前的 Window。
win = Application.Current.MainWindow
注意,在 app.run() 之前,Current.MainWindow 还是 null。

Application 上有几个函数,如果想改写,需要继承 Application
OnStartup(), Run() 启动时调用
OnSessionEnding(), Windows 退出当前用户(Session)时调用
OnExit(), App 退出时调用

InheritTheApp.cs
-------------------------------------------------------
using System;
using System.Windows;

namespace Petzold.InheritTheApp
{
    class InheritTheApp : Application
    {
        [STAThread]
        public static void Main()
        {
            InheritTheApp app = new InheritTheApp();
            app.Run();
        }

        protected override void OnStartup(StartupEventArgs args)
        {
            base.OnStartup(args);

            Window win = new Window();
            win.Title = "Inherit the App";
            win.Show();
        }

        protected override void OnSessionEnding(SessionEndingCancelEventArgs args)
        {
            base.OnSessionEnding(args);

            MessageBoxResult result = MessageBox.Show("Do you want to save your data?",
                MainWindow.Title, MessageBoxButton.YesNoCancel,
                MessageBoxImage.Question, MessageBoxResult.Yes);
        }
    }
}
-------------------------------------------------------

Application.Windows 属性是一个 ICollection/IEnumerable,保存了当前启动的所有 Window
Application.MainWindow 是第一个创建的 Window,如果此 Window 关闭,则 MainWindow == null

ThrowWindowParty.cs
-------------------------------------------------------
using System;
using System.Windows;
using System.Windows.Input;

namespace Petzold.ThrowWindowParty
{
    class ThrowWindowParty : Application
    {
        [STAThread]
        public static void Main()
        {
            ThrowWindowParty app = new ThrowWindowParty();
            app.Run();
        }

        protected override void OnStartup(StartupEventArgs args)
        {
            Window winMain = new Window();
            winMain.Title = "Main Window";
            winMain.MouseDown += WindowOnMouseDown;
            winMain.Show();

            for (int i = 0; i < 2; ++i)
            {
                Window win = new Window();
                win.Title = "Extra Window No. " + (i+1);
                win.Show();
            }
        }

        void WindowOnMouseDown(object sender, MouseButtonEventArgs args)
        {
            Window win = new Window();
            win.Title = "Modal Dialog Box";
            win.ShowDialog();
        }
    }
}
-------------------------------------------------------

不显示于 taskbar
win.ShowInTaskbar = False

默认情况,Application.Run() 在所有 Window 关闭后返回。
可以通过 Application.ShutdownMode 控制此行为。
System.Windows.ShutdownMode
  OnMainWindowClose
  OnLastWindowClose
  OnExplicitShutdown, 等待 app.Shutdown() 调用才返回

通过设置 Owner 可以形成从属关系,如下可以让 win 成为 winMain 的 modeless dialog
win.Owner = winMain

一个完整的 WPF 程序,一般会继承 Application 和 Window。
Main.cs,主入口
MyApplication.cs,继承 Application
MyWindow.cs,继承 Window

如果不需要继承 Application,也可以:
new Appliation().Run(new MyWindow());

Window.Width, Window.Height 可以设置窗体大小,初始值为 NaN。
读取窗体大小,请用 Window.ActualWidth, Window.ActualHeight,初始值为 0。

Window.OnKeyUp() 和 OnKeyDown() 可以用来接收按键信息。

如果想接收 Unicode Input,请用 Window.OnTextInput()。中文也能接收哦。

一些 mode 设置
Window.WindowStyle,
Window.ResizeMode,是否可以改变大小
Window.WindowState,最大/最小化

  评论这张
 
阅读(105)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017