WPF工作笔记:本地化支持、主进程通知、两种最常用异步编程方式_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > WPF工作笔记:本地化支持、主进程通知、两种最常用异步编程方式

WPF工作笔记:本地化支持、主进程通知、两种最常用异步编程方式

 2014/11/6 18:24:39  心梦缘  程序员俱乐部  我要评论(0)
  • 摘要:1、本地化支持(1)覆盖控件默认的依赖属性LanguagePropertyFrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement),newFrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));(2)在项目资源文件中添加Resources.resx,Resources
  • 标签:

1、本地化支持

(1)覆盖控件默认的依赖属性LanguageProperty

FrameworkElement.LanguageProperty.OverrideMetadata(
                typeof(FrameworkElement), new FrameworkPropertyMetadata(
                    XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

(2)在项目资源文件中添加Resources.resx,Resources.zh-CN.resx等等本地化字符串资源。

       文件中依次输入Key-Value键值对,key相同,Value中输入本地化语言字符串,如下所示

       

        

(3)在界面中引用资源文件所在命名空间。如:

class="brush:csharp;gutter:true;">xmlns:resc="clr-namespace:WpfApplication.Resources"

 

(4)引用字符串资源。如 :

<Button Content="{x:Static resc:Resources.Open}"/>

 

2、主进程通知

    在多文件支持和音视频播放界面应用中,经常需要在外部通知主进程。比如您已经打开了酷狗音乐播放界面,在外部文件夹中,双击.mp3音乐文件,不会启动第二个酷狗音乐播放界面,而是通知主窗口接收外部请求。下面给出一种实现方式:

    首先声明WPF开发的系统只有一个入口,那就是Application类,也就是App.xaml

(1)App.xaml中不需要StartupUri,在后台启动主窗口。首先在App.xaml.cs中定义事件句柄,用于通知主窗口

public static EventWaitHandle ProgramStarted;
private bool CreatedNew;

(2)App.xaml.cs重写OnStartup,判断是否需要新建主窗口

ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, "MyStartEvent", out CreatedNew);

    通过上面语句得到的CreatedNew值来决定是否需要创建主窗口,CreatedNew等于true时按一般情况声明主窗口:

if (CreatedNew)
{
      MainWindow mainWin = new MainWindow();
      mainWin.Show();
}

(3)下面才是重点,在主窗口已经启动的情况下,如何将外部的文件传递到主窗口去

     因为前面已经定义了事件句柄ProgramStarted,我们首先需要将外部文件写入到一个本地文件或者注册表中(名其为Global),已经启动的窗口进程得到通知后,去读取新建App进程写入的内容。

     然后调用ProgramStarted.Set();Thread.Sleep(100);主窗口就可以得到通知。

(4)主窗口的线程池中需要注册Wait请求:

    MainWindow.xaml.cs构造函数中:

ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);

    事件回调处理函数:

        /// <summary>
        /// 主进程在接收到其他进程通知后回调函数
        /// </summary>
        /// <param name="state"></param>
        /// <param name="timeout"></param>
        private void OnProgramStarted(object state, bool timeout)
        {
            Thread thread = new Thread(new ThreadStart(new Action(() =>
            {
                this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (System.Threading.ThreadStart)delegate()
                {
                    //处理Global
                });
            })));
            //因为是线程池通知主进程,必须在单线程单元ApartmentState.STA执行
            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
        }

  注意上面代码中使用了Dispatcher,只有WPF这样使用,能够访问主窗口控件,因为主窗口控件所在的线程是主窗口,不能在新建的线程中调用,如果要使用,需要使用Dispatcher。

      默认Dispatcher执行的环境也是ApartmentState.STA,所以上面的代码可以简单为(只能在WPF中可以这样使用):

        private void OnProgramStarted(object state, bool timeout)
        {
                this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (System.Threading.ThreadStart)delegate()
                {
                   //处理Global
                });
        }

 

3、两种最常用异步编程

(1)DispatcherObject

            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
            {
                // Simulate some work taking place.
                Thread.Sleep(TimeSpan.FromSeconds(5));
                btnContent.Text = "Here is some new text.";
            }
            );

  

(2)BackgroundWorker

BackgroundWorker是WPF异步编程经常使用的类,使用方式比较正规,很容易学会。

BackgroundWorker bgw = new BackgroundWorker();
bgw.WorkerSupportsCancellation = true;
bgw.WorkerReportsProgress = true;
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
bgw.RunWorkerAsync(argument);

  

//bgw_DoWork不能直接使用主线程元素,只能通过e.Argument得到主线程传过来的参数
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
    string argument= e.Argument.ToString();
    e.Result = new LongTimeFun(argument);
}

private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    MyObject  obj = e.Result as MyObject ;
    //这个时候才能使用主界面控件元素
}

private  MyObject LongTimeFun(string argument){

}

  

上一篇: 工商总局叫停双11折扣价:京东天猫都慌了 下一篇: 没有下一篇了!
  • 相关文章
发表评论
用户名: 匿名