WPF学习笔记(3)

1.

播放音频

MediaElement 的LoadedBehavior 需要设置为Manual,这样才可以手动控制视频的播放状态。

详细参见 http://www.cnblogs.com/gnielee/archive/2010/05/06/wpf4-media-player-mediaelement.html

    <StackPanel>
        <Button Click="cmdPlay_Click" Margin="5" Padding="5">Play</Button>
        <Image Name="img" Margin="5" Source="Images/Blue hills.jpg"></Image>
      <MediaElement Name="Sound" Source="Sounds/start.wav" LoadedBehavior="Manual"></MediaElement>
    </StackPanel>

  c#代码

        private void cmdPlay_Click(object sender, RoutedEventArgs e)
        {
            img.Source = new BitmapImage(new Uri("images/winter.jpg", UriKind.Relative));
            //img.Source = new BitmapImage(new Uri("pack://application:,,,/images/winter.jpg"));
            Sound.Stop();
            Sound.Play();
        }

  

2.

WPF单体模式

1、在程序启动时,通过进程来查找进程名;

2.使用Mutex同步基元来实现;

3.使用Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase类来实现,此类在Microsoft.VisualBasic.dll程序集中。

第1、2方法的缺点是应用程序之间就缺乏通信机制,例如:word,但你打开2个word文档,肯定只有一个word应用程序,但是有两个窗口,此时,word应用程序之间肯定需要通信机制。

第3种方法可以实现应用程序通信机制。下面就不卖关子了,直接上代码了。

    //应用程序启动类
    public class Startup
    {
        [STAThread]
        public static void Main(string[] args)
        {            
            SingleInstanceApplicationWrapper wrapper = new SingleInstanceApplicationWrapper();
            wrapper.Run(args);        
        }
    }
    
    //单例应用程序启动包装类
    public class SingleInstanceApplicationWrapper : 
        Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
    {        
        public SingleInstanceApplicationWrapper()
        {
            //确定此应用程序是否为单例应用程序,此属性很重要
            this.IsSingleInstance = true;
        }      

        //应用程序对象
        private App app;

       //应用程序启动时运行,e包含应用程序的命令行参数,并指示是否应取消应用程序启动。
       //此方法的返回值:指示应用程序是否应继续启动
        protected override bool OnStartup(
            Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
        {  
            app = new WpfApp();
            app.Run();
            //指示应用不继续启动了,千万不能返回true,因为上面的app.run()方法已经启动了应用程序。
            return false;
        }

        //在单实例应用程序的后续实例启动时运行
        //参数e:包含后续应用程序实例的命令行参数,并且指示第一个应用程序实例是否应在退出异常处理程序后进入前台。
        //这个方法很重要,当另一个应用程序启动时(本应用程序的另一个实例),会触发此方法,此方法是新建一个窗口,但不创建新的应用程序。
        protected override void OnStartupNextInstance(
            Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e)
        {
            if (e.CommandLine.Count > 0)
            {                
                app.ShowCommandArgs(e.CommandLine[0]);
            }
        }
    }
    
    //应用程序类
    public class App : System.Windows.Application
    {
        protected override void OnStartup(System.Windows.StartupEventArgs e)
        {
            base.OnStartup(e);           
            Window1 win= new Window1();
            //主窗口
            this.MainWindow = win;
            win.Show();
            // 命令行参数
            if (e.Args.Length > 0) 
            {
                ShowCommandArgs(e.Args[0]);
             }
        }
        
        //显示命令行参数
        public void ShowCommandArgs(string args)
        {
            try
            {                
                Window2 win=new Window2(); 
                win.Content=args;   //显示命令行参数     
                win.Owner = this.MainWindow;
                win.Show();
                win.Activate(); //激活当前窗口              
            }
            catch
            {
                MessageBox.Show("Could not show args.");
            }
        }
    } 

  

另外在实现的时候需要注意:

(*) 需要添加Microsoft.VisualBasic.dll的程序集引用

(*) the application needs to start with a traditional Main() method, rather than an App.xaml file.

注意:

你刚开始建的项目类型可能是WPF,在项目的属性里,application标签下有个Startup Object,一开始默认应该是“你的namespace.App”,除此之外就只有Not Set了,没别的可选。是因为Main函数才是程序的入口,VS会根据Main函数去搜寻哪些可以作为Startup Object。但我们查看App这个类的代码会发现,默认情况下里面并没有Main函数,这是怎么回事呢?原来VS在编译时会结合xaml自动把代码补充完整。xaml里面的x:Class="你的namespace.App”,其中"你的namespace.App”会作为可选的Startup Object出现。
当在别的类里面新加入了Main函数,就会把这个类也列在Startup Object的可选列表中(有时候可能要重启VS才能在Startup Object里看到新的项)。 针对上面的例子(文件名是Startup.cs)则把“命名空间.Startup”作为Startup Object.

 3.

Application关闭模式

有些应用程序是单窗体的,如记事本,VS IDE等等,关闭窗体就关闭了整个应用程序,有些应用程序的多窗体的或是生命周期是独立于窗体的(如Office),这时候就根据ShutdownMode属性来觉得关闭应用程序的方式:

namespace System.Windows
{
    public enum ShutdownMode
    {
        OnLastWindowClose = 0, // default
        OnMainWindowClose = 1,
        OnExplicitShutdown = 2,
    }
}

  OnMainWindowClose是单窗体应用程序的关闭模式,OnLastWindowClose是多窗体应用程序的关闭模式,另外,两种模式还可以调用Shutdown方法来关闭应用程序。在OnExplicitShutdown模式下,只能调用Shutdown方法来关闭应用程序。

public partial class Window1 : System.Windows.Window
 {
...
void shutdownButton_Click(object sender, RoutedEventArgs e)
   {
    Application.Current.Shutdown();
   }
}

  你可以在代码中随时修改关闭模式属性,也可以通过xaml文件来配置:

<Application

x:Class="AppWindowsSample.App"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

StartupUri="Window1.xaml"

ShutdownMode="OnExplicitShutdown" />

  提示:虽然有很多中方式可以关闭应用程序,但是最好的方式还是调用Shutdown方法,在调用方法的过程中可以使窗体产生Closing和Closed的消息,从而在事件中停止关闭不应该关闭的情况。

4.

Application事件:

Application生命周期中提供的事件有:

• Startup

• Activated

• Deactivated

• DispatcherUnhandledException

• SessionEnding

• Exit

Startup事件:

当Application的run方法调用的时候引发的事件,这时候是适合做些全局初始化的操作,例如处理命令行参数

void App_Startup(object sender, StartupEventArgs e) {

for (int i = 0; i != e.Args.Length; ++i) {

// do something useful with each e.Args[i]

...

  }

}

  

Activated和Deactivated事件:

当Application中的一个top level 窗体获得焦点时触发Activated事件,也就是应用程序被激活时。当用户从本应用程序切换到其他应用程序时触发Deactivated事件。这两个事件在恢复和暂停应用程序时非常有用:

void App_Activated(object sender, EventArgs e) {

ResumeGame( );

}

void App_Deactivated(object sender, EventArgs e) {

PauseGame( );

}

  

DispatcherUnhandledException事件

Dispatcher是将窗体事件路由到发生事件源的类,也包括对未处理异常的处理,在这个事件中可以做一些异常处理:

void App_DispatcherUnhandledException(

object sender, DispatcherUnhandledExceptionEventArgs e) 
{

string err = "Oops: " + e.Exception.Message);

MessageBox.Show(err, "Exception", MessageBoxButton.OK);

// Only useful if you've got some way of guaranteeing that

// your app can continue reliably in the face of an exception

// without leaving this AppDomain in an unreliable state...

//e.Handled = true; // stop exception from bringing down the app

}

  SessionEnding事件:

当Windows的Session关闭时触发,如关机,注销或重启的时候:

void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)

{
  if (MessageBox.Show(
  e.ReasonSessionEnding.ToString(),
  "Session Ending",
  MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
  {
   e.Cancel = true; // stop the session from ending
  }
}

  一共有两种类型:

namespace System.Windows

{

    public enum ReasonSessionEnding

    {

        Logoff = 0,

        Shutdown = 1,

    }

}

  

Exit事件:

当Application退出时触发,无论最后一个窗体是否关闭,或是调用Shutdown方法,或是session关闭。

其中一个方法的重载返回int型数值,让你可以在喜欢的Win32APIs中调用,默认返回0,你也可以自己重新设定。

void App_Exit(object sender, ExitEventArgs e) 
{

e.ApplicationExitCode = 452; // keep 'em guessing...

}

  

原文地址:https://www.cnblogs.com/DragonX/p/3478235.html