WPF工作笔记:本地化支持、主进程通知、两种最常用异步编程方式
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)在界面中引用资源文件所在命名空间。如:
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){ }
简单形式(Lambda语法):
BackgroundWorker bgw = new BackgroundWorker();
bgw.WorkerSupportsCancellation = true;
bgw.WorkerReportsProgress = true;
bgw.DoWork += new DoWorkEventHandler((sender, e) => {
e.Result = new LongTimeFun(argument);
});
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler((sender, e) => {
MyObject obj = e.Result as MyObject ;
});
(3)DispatcherObject和BackgroundWorker结合使用
我们知道BackgroundWorker的DoWork事件回调事件中不能使用界面元素,但是在WPF中可以结合使用DispatcherObject、BackgroundWorker达到目的,
这样就不需要BackgroundWorker的RunWorkerCompleted回调事件了。(这个几乎在书本和其它技术资料中没有介绍,但是很多时候是很有用的)
BackgroundWorker bgw = new BackgroundWorker();
bgw.WorkerSupportsCancellation = true;
bgw.WorkerReportsProgress = true;
bgw.DoWork += new DoWorkEventHandler((sender, e) =>
{
this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (System.Threading.ThreadStart)delegate()
{
//这样DoWork回调事件中可以使用主界面控件元素
});
});
bgw.RunWorkerAsync();
4、滚动条内容设置可见
(1)使用FrameworkElement方法 BringIntoView
FrameworkElement.BringIntoView();
(2)ListBox
listbox.ScrollIntoView(listbox.Items[index]);
(3)Scrollviewer
scrollViewer.ScrollToVerticalOffset(VisualTreeHelper.GetOffset(VisualObject).Y);
WPF工作笔记:本地化支持、主进程通知、两种最常用异步编程方式的更多相关文章
- [操作系统知识储备,进程相关概念,开启进程的两种方式、 进程Queue介绍]
[操作系统知识储备,进程相关概念,开启进程的两种方式.进程Queue介绍] 操作系统知识回顾 为什么要有操作系统. 程序员无法把所有的硬件操作细节都了解到,管理这些硬件并且加以优化使用是非常繁琐的工作 ...
- WPF程序将DLL嵌入到EXE的两种方法
WPF程序将DLL嵌入到EXE的两种方法 这一篇可以看作是<Visual Studio 版本转换工具WPF版开源了>的续,关于<Visual Studio 版本转换工具WPF版开源了 ...
- Day9 进程理论 开启进程的两种方式 多进程实现并发套接字 join方法 Process对象的其他属性或者方法 守护进程 操作系统介绍
操作系统简介(转自林海峰老师博客介绍) #一 操作系统的作用: 1:隐藏丑陋复杂的硬件接口,提供良好的抽象接口 2:管理.调度进程,并且将多个进程对硬件的竞争变得有序 #二 多道技术: 1.产生背景: ...
- Javscript轮播 支持平滑和渐隐两种效果(可以只有两张图)
原文:Javscript轮播 支持平滑和渐隐两种效果(可以只有两张图) 先上两种轮播效果:渐隐和移动 效果一:渐隐 1 2 3 4 效果二:移动 1 2 3 4 接下来,我们来大致说下整个轮播的思 ...
- Javascript轮播 支持平滑和渐隐两种效果
Javascript轮播 支持平滑和渐隐两种效果 先上两种轮播效果:渐隐和移动 效果一:渐隐 1 2 3 4 效果二:移动 1 2 3 4 接下来,我们来大致说下整个轮播的思路: 一.先来看简单的 ...
- delphi杀进程的两种方式
delphi杀进程的两种方式 uint unit Tlhelp32; 第一种:比较简单,根据标题,找到窗口,再找到进程,杀死进程 procedure KillProgram(WindowTitle : ...
- nginx将http升级到https并且同时支持http和https两种请求、http自动转向https
1.http升级到https 1.1.检查 Nginx 是否支持 SSL /usr/local/nginx/sbin/nginx -V configure arguments中是否有--with-ht ...
- 【Nginx】将http升级到https并且同时支持http和https两种请求
一.如何将http升级到https 需要满足下面三个: 1.域名 2.nginx 3.SSL证书 一般第三方证书颁发机构下发的证书是收费的,一年好几千. 1) 从腾讯云申请免费的SSL证 ...
- Nginx配置同一个域名同时支持http与https两种方式访问
Nginx配置同一个域名http与https两种方式都可访问,证书是阿里云上免费申请的 server{listen 80;listen 443 ssl;ssl on;server_name 域名;in ...
随机推荐
- winform异步进度条LongTime
winform异步进度条LongTime,运用到回调函数 定义事件的参数类: namespace LongTime.Business { // 定义事件的参数类 public class ValueE ...
- 【转】SQL Server 2008下载 (附注册码)
SQL Server 2008 中文试用版下载地址:http://sqlserver.dlservice.microsoft.com/dl/download/B/8/0/B808AF59-7619-4 ...
- 转——Android应用开发性能优化完全分析
[工匠若水 http://blog.csdn.net/yanbober 转载请注明出处.] 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉 ...
- Maven本地资源库
在本地安装的mvn文件夹中找到conf/setting.xml,然后找到localRepository结点,这个路径值就是Maven的实际路径 打开该文件夹就能够看到
- Quick Sort
class Program { static int[] a = new int[] { 6, 1, 2, 7, 9, 3, 4, 5, 10, 8 }; int n; static void Mai ...
- Django基础篇之数据库选择及相关操作
在djanjo框架中我们最常用的框架分别就是mysql和sqlit了,下面我们将分别讲述一下这俩种数据库的基础必备知识 mysql 一.利用命令创建(在终端上执行) 1.首先创建一个project项目 ...
- oracle修改连接空闲自动断开
空闲3分钟自动断开 SELECT * FROM DBA_PROFILES; CREATE PROFILE KILLIDLE LIMIT IDLE_TIME ; alter PROFILE DEFAUL ...
- oracle 将查询到的数据插入表
1. 新增一个表,通过另一个表的结构和数据 create table tab1 as select * from tab2 2. 如果表存在: insert into tab1 select * fr ...
- php 导出csv
public function doworks(){ //输出Excel文件头,可把user.csv换成你要的文件名 header('Content-Type: appli ...
- 用PHP实现守护进程任务后台运行与多线程(php-resque使用说明)
消息队列处理后台任务带来的问题 项目中经常会有后台运行任务的需求,比如发送邮件时,因为要连接邮件服务器,往往需要5-10秒甚至更长时间,如果能先给用户一个成功的提示信息,然后在后台慢慢处理发送邮件的操 ...