精华内容
下载资源
问答
  • 由于最近在做wpf版的截图软件,在处理全局热键的时候,...最终,我找到了,wpf本身就支持处理系统的键盘消息(包括热键)。 使用ComponentDispatcher类处理键盘消息 下面贴上代码,方便大家复制粘贴: public...

    由于最近在做wpf版的截图软件,在处理全局热键的时候,发现国内博客使用的都是winform窗体的键盘处理方式,此方式需要使用winform的动态库,如此不协调的代码让我开始在github中寻找相关代码。

    最终,我找到了,wpf本身就支持处理系统的键盘消息(包括热键)。

    使用ComponentDispatcher类处理键盘消息

    下面贴上代码,方便大家复制粘贴:

    public static class HotkeyListener
        {
            /// <summary>
            ///     热键消息
            /// </summary>
            const int WindowsMessageHotkey = 786;
            /// <summary>
            ///     demo的实例句柄
            /// </summary>
            public static IExcuteHotKey Instance = null;
            static HotkeyListener()
            {
                //  注册热键(调用windows API实现,与winform一致)
                Hotkey hotkey = new Hotkey(Keys.F2, Modifiers.None, true);
                //  处理热键消息(使用wpf的键盘处理)
                ComponentDispatcher.ThreadPreprocessMessage += (ref MSG Message, ref bool Handled) =>
                {
                    //  判断是否热键消息
                    if (Message.message == WindowsMessageHotkey)
                    {
                        //  获取热键id
                        var id = Message.wParam.ToInt32();
                        //  执行热键回调方法(执行时需要判断是否与注册的热键匹配)
                        Instance.ExcuteHotKeyCommand(id);
                    }
                };
            }
        }
    
    
    

    关于ComponentDispatcher的说明

     

    转载于:https://www.cnblogs.com/zhuxiaoxiao/p/11420359.html

    展开全文
  • WPF 利用HwndSource拦截Windows消息

    千次阅读 2017-09-21 14:07:04
    WPF提供了一个HwndSource可以使你更快的实现处理Windows消息。 通过HwndSource.FromHwnd得到的HwndSource可以添加(AddHook)移除(Remove)Hook 首先注册SourceInitialized事件,在事件中创建一个HwndSource对象, ...

    WPF提供了一个HwndSource可以使你更快的实现处理Windows消息。

    通过HwndSource.FromHwnd得到的HwndSource可以添加(AddHook)移除(Remove)Hook

    首先注册SourceInitialized事件,在事件中创建一个HwndSource对象,

    然后利用其AddHook方法来将所有的windows消息附加到一个现有的事件中,本例子中WpfHandleWinowMsg,这是自己定义的用来处理具体逻辑的函数。

     

    简单来说就是:

    获取本窗体的句柄hs,然后hs.AddHook一个自定义方法即可

     

    代码如下:

     public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                SourceInitialized += HandleInitialized;
            }
    
            public void HandleInitialized(object o,EventArgs e)
            {
                IntPtr wptr = new WindowInteropHelper(this).Handle;
                HwndSource hs = HwndSource.FromHwnd(wptr);
                hs.AddHook(new HwndSourceHook(WpfHandleWinowMsg));
            }
    
            public IntPtr WpfHandleWinowMsg(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
            {   
                //这个函数可以做很多事情,只要是windows消息都会经过,例如注册全局快捷键,修改窗体大小边框,等等
                //也可以调API做对应的事情
                switch (msg)
                {
                    case 1:
                        break;
                    case 2:
                        break;
                    default:
    
                        break;
                }
                return IntPtr.Zero;
            }
        }

     

     

     

     

    顺带说下Winform,直接重载WndProc函数即可

    public partial class Form1 : Form
    {
           int WM_NCLBUTTONDBLCLK = 0xA3;
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_NCLBUTTONDBLCLK)
                {
                    if (this.Height < 35)
                    {
                        this.Height = h;
                    }
                    else
                    {
                        h = this.Height;
                        this.Height = -10;
                    }
                    return;
                }
                base.WndProc(ref m);  //让基类去处理
            }
    }

     

     

     

    展开全文
  • 这一篇实现MVVMLight 消息机制 WPF 中实现View 与ViewMode 之间的通信 ...首先MVVMlight 里的Messenger来实现发送消息消息注册 先定义一个类EditBookArgs 这个类是拿来传参的 比如 传入 编辑窗...

    这一篇实现MVVMLight 消息机制

    WPF 中实现View 与ViewMode 之间的通信 

    比如 我们实现 Main窗体 在点击新增的时候 或者修改的时候 实现Show出一个窗体 点击修改的时候并把选中的值传入修改窗体

     

    首先MVVMlight 里的Messenger  来实现发送消息 与消息的注册

    先定义一个类EditBookArgs 这个类是拿来传参的   比如 传入 编辑窗体(一般新增和编辑窗体为一个窗体) 的对象  

    IsEdit 是来区分点击的是编辑窗体还是新增窗体

        public class EditBookArgs
        {
            private bool isEdit;
    
            public bool IsEdit
            {
                get { return isEdit; }
                set { isEdit = value; }
            }
            private Book book;
            public Book Book
            {
                get { return book; }
                set { book = value; }
            }
    
    }

    在MainViewModel中 发送消息

           private void edit(Book obj)
           {
               Messenger.Default.Send(new EditBookArgs { Book = obj, IsEdit = true });
           }
    
           private void add()
           {
               Messenger.Default.Send(new EditBookArgs {IsEdit = false });
           }

    在Mainwindow 里 注册消息

            public MainWindow()
            {
                InitializeComponent();
                Messenger.Default.Register<EditBookArgs>(this, Onmake);
                this.Unloaded += MainWindow_Unloaded;
            }
    
            void MainWindow_Unloaded(object sender, RoutedEventArgs e)
            {
                Messenger.Default.Unregister<EditBookArgs>(this, Onmake);
            }
    
            private void Onmake(EditBookArgs obj)
            {
                EditBookwindow window = new EditBookwindow();
               // (window.DataContext as IeditBook).EditBookArgs = obj;
               var result= window.ShowDialog();
               if (result.HasValue && result.Value) 
               {
                  
               }
            }

    在这里说一下代码意思

    我们Main窗体注册了一个消息  在MainViewModel 里用触发事件 发送消息 用send来发送消息内容

    现在我们 在界面获得了 参数 也可以new一个Edit窗体 我们怎么把参数传入Edit那 一种在Edit窗体 定义一个对象

    但是这样会让程序耦合  这里做一个接口

    EditViewModel 继承这个接口  在EditViewModel里就可以随意使用 接口对象 来对Edit里面的对象赋值

       public interface IeditBook
        {
             EditBookArgs EditBookArgs { get; set; }
        }

    EditBookViewModel 里面有一个显示 relayCommand

    
            private void viewl()
            {
                if (EditBookArgs.IsEdit)
                {
                    CurrentBook = new Book
                    {
                        Id = EditBookArgs.Book.Id,
                        Author = EditBookArgs.Book.Author,
                        Description = EditBookArgs.Book.Description,
                        Pages = EditBookArgs.Book.Pages,
                        Title = EditBookArgs.Book.Title
                    };
                }
                else 
                {
                    CurrentBook = new Book { Id = Guid.NewGuid() };
                }
                WindowTitle = EditBookArgs.IsEdit ? "编辑" : "新增";
            }

    看不懂 没关系 我最后会把代码传到最后一篇MVVMlight文章里

    展开全文
  • 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中的实现(三)命令绑定 MVVM模式解析和...

    MVVM模式解析和在WPF中的实现(六)

    用依赖注入的方式配置ViewModel并注册消息

    系列目录:

    MVVM模式解析和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(二)数据绑定

    MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(四)事件绑定

    MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信 

    MVVM模式解析和在WPF中的实现(六)用依赖注入的方式配置ViewModel并注册消息

    0x00 最初的想法

    这次主要讨论下给View指定ViewModel的事情。一般来说给View指定ViewModel常用的方式有两种,一种是在View的后台代码中写DataContext = new ViewModel(),还有一种是在XAML中指定View的DataContext。这两种方式都使得View对ViewModel产生了依赖,这种情况下可以考虑用依赖注入的方式使取消View对ViewModel的直接依赖。依赖注入一般来说可以通过构造函数注入、通过设置属性注入,这两种方法对于View来说都不合适。因此可以使用IoC Container,让View主动去获取对应的ViewModel。

    其实给View指定一个ViewModel并不属于频繁的操作,而且改起来也很容易,费半天劲搞个依赖注入确实不太至于。就像上篇文章中废了半天劲搞了个View和ViewModel的通信一样,用到的概率比较小,而且也有别的方式解决,虽然那种方式并不符合MVVM模式。不过View除了依赖ViewModel之外对消息注册器也是会产生依赖的,而且某种类型的View一般来说都依赖固定类型的ViewModel和消息注册器,因此可以一次注入两个依赖,这样貌似就值了,至少我认为是值了,所以有了ViewModelManager这个类。

    0x01 ViewModel和MessageManager的依赖注入

    使用静态类ViewModelManager来当作IoC Container。往IoC Container里注册依赖关系一般有两种方式,一种是将依赖关系以某种形式(例如xml)保存在外部,一种是在程序中注册到一个列表里。我采取第二种做法,因为比较容易:)

    程序在启动时使用ViewModelManager.Register将依赖关系注册到ViewModelManager中,View在构造函数中调用ViewModelManager.SetViewModel(this);来设置View的DataContext并通过依赖的消息注册器注册消息,消息注册器可以为空,代表View不接收消息。它们的关系如图所示:

     

    需要说明的有两个地方:

    一个是View和ViewModel的对应关系。一般来说一个View对应着一种ViewModel,这样注册起来是没问题的。但这个并不绝对,理论上来说一个View可以将DataContext设置为任意ViewModel,如果一个View可以设置多种ViewModel该如何处理呢,这时候可以在ViewModelManager注册时添加Token属性,然后用SetViewModel(this,token)的方式指定特定的ViewModel为DataContext。

    另一个是消息注册的范围。因为一般来说ViewModel都是和绑定的View通信。所以默认情况下,消息注册到单独一个MessageManager中,这个MessageManager保存ViewModel中,ViewModel使用这个MessageManager发送消息,发送的消息由View接收。但如果需要和其他View通信,需要把消息注册到MessageManager.Default中,这个对象是static的,要达到这个目的只要在View设置ViewMode时这样来SetViewModel(this,isGlobalMsg:true)即可。如果ViewModel又想和绑定的View单独通信,有时候还需要和别的View通信,可以在消息注册器中注册时将需要单独通信的消息设置一个Group,ViewModel在发送消息时加一个Group过滤一下即可。一个Group可以理解为消息的单独一个通道。

    顺带一提,好吧只是顺带一提的是,在给View注入ViewModel时,顺便把ViewModel的UIDispatcher属性设置为了View的Dispatcher,虽然我不知道这有什么用。但这样在ViewModel中使用UIDispatcher时即为相关的View的Dispatcher。如果要使用MainWindow的Dispatcher可以通过DispatcherHelper.Dispatcher或者App.Current.MainWindow.Dispatcher获得。

    0x02 写在最后

    到此为止我能想到的MVVM框架的功能算是基本实现了,遇到的需求十分有限,才能也十分有限,能想到的就这几个了,欢迎回复讨论,也欢迎加我QQ16141860交流。之前一直是在TestArea这个仓库里进行测试,现在这个小框架整理了下,放到AyxMVVM仓库里了。现在有些想法还不太成熟,使用过程中遇到问题也会随时修正,以后就都修改到AyxMVVM中了,TestArea中的MyMVVM不再维护了。另外给仓库起名真是件麻烦事,干脆统一都用Ayx+XXX的方式,这样既容易重复的概率又十分小。Ayx是我名字拼音的首字母,想想看以拼音A开头的姓氏之少就能想到几乎不会出现重复了。最后,10月6日看了微软的秋季产品发布会后信仰充值成功。对UWP十分感兴趣,下一步打算学习一下。

    0x03 关于AyxMVVM

    https://github.com/durow/AyxMVVM

     


    更多内容欢迎访问我的博客:http://durow.vip

    转载于:https://www.cnblogs.com/durow/p/4870249.html

    展开全文
  • Events称为事件,是Windows消息机制中的重要概念之一,也是最常见的人机交互手段之一。XAML和其他开发语言类似,具有事件机能,帮助应用管理用户输入,执行不同的行为。根据用户不同的操作,执行不同的业务逻辑代码...
  • 不过View除了依赖ViewModel之外对消息注册器也是会产生依赖的,而且某种类型的View一般来说都依赖固定类型的ViewModel和消息注册器,因此可以一次注入两个依赖,这样貌似就值了,至少我认为是值了,所以有了...
  • WPF中的事件我们称之为路由事件。那么它和.NET的传统事件有什么区别了。我们首先来了解下路由事件。路由事件是可以在UI树形结构进行传递的。也就是说激发控件可以把这个事件消息传递到根节点上去。在树形节点上,...
  • WPF 路由事件

    2019-09-24 14:15:39
    当有意义的事情发生时,由对象发送的用于通知代码的消息。 事件路由允许源自某个元素的事件由另一个元素引发。 比如·来自工具栏按钮的单击事件可在代码处理之前上传到工具栏,然后上传到包含工具栏的窗口。 定义...
  • 原文:WPF MVVM下做发送短信小按钮 最近做一个项目,因为涉及到注册,因此需要发送短信,一般发送短信都有一个倒计时的小按钮,因此,就做了一个,在此做个记录。 一、发送消息  没有调用公司的短信平台,只是...
  • 最近做一个项目,因为涉及到注册,因此需要发送短信,一般发送短信都有一个倒计时的小按钮,因此,就做了一个,在此做个记录。 一、发送消息  没有调用公司的短信平台,只是模拟前台生成一串数字,将此串数字输出...
  • 老规矩,先看效果 右下角的notification: 操作中心的notification: 整体效果: ...2.在注册表里注册你实现了...3.一个APP_ID,添加到快捷方式里,ActionCenter会以此来区分不同应用的消息。 缺一...
  • 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中...MVVM模式解析和在WPF中的实现(六)用依赖注入的方式配置ViewModel并注册消息 ...
  • 我们在上一篇 说到 用消息把参数传到EditViewMode里 用RelayCommand 注册一个View事件 但是我们发现通过Icommand中绑定的Command 默认只能是点击事件 怎么使用loaded方法 或者使用 MouseEnter之类的事件那?...
  • 和依赖属性、附加属性一样,从节省资源的角度,从事件(消息通知方式)进行了升级。 与依赖属性一样,可以通过传统的方式使用路由事件,但具有更强的传播能力----可以在元素叔向上冒泡,和向下隧道传播,并且沿着...
  • 本文只是博主用来记录笔记,误喷 使用到到了MVVM中消息...第一步:在需要关闭窗体中注册消息   1 public UserView() 2 { 3 this.DataContext = new UserViewModel(); 4 InitializeComponent(); 5 ...
  • 上次我们说到Dispatcher内部有一个管理DO的队列,我暂且称之为DOQueue,在本文我就来重点说DO的处理机制,首先我们来看看DO是怎样被创建的,wpf并没有改变太多win32的内核,消息循环的机制已经深入人心了,同样窗体...
  • WPF:MVVM模式下ViewModel关闭View

    千次阅读 2017-01-23 20:51:58
    2、UI的后台代码中,注册IsEnableChange事件,在这个事件里,检测到传过来的值满足某个条件,即可触发Close()命令 如此,VM控制自己那个属性就能达到关闭V的目的了。 二、参数传递。 根据参数传递的不同。分为传递...
  • 介绍一下如何在实例中相互操作,比如在程序A中调用程序B中的方法,看...注册一个新的窗口消息,该消息确保在系统中是唯一的,返回消息值,可在下面SendMessage函数中调用,如果该消息已经存在,则返回它的消息值IntP...
  • 1、Messager交互结构和消息类型 ...Messenger类用于应用程序的通信,接受者只能接受注册消息类型,另外目标类型可以被指定,用Send&lt;TMessage, TTarget&gt;(TMessage message)实现...
  • WPF中的事件(二)- 自定义路由事件

    千次阅读 2016-08-22 08:55:33
    自定义路由事件的添加,共分为三个步骤:1、声明并注册路由事件 2、为路由事件添加CLR事件包装 3、创建可以激发路由事件的方法 以下实例,实现的功能是创建一个Button,每次点击该Button时激发自定义的路由事件...
  • 今天翻译一段MVVM light tookit中的一些说明文档。组件资源(来自翻译)本toolkit包含了以下一些针对WPF、Sliverlight及WP7的组件和类库:1、...消息获取方只接受注册消息类型。此外,可以指定消息类型,只在符...
  • 依赖项属性

    2016-03-04 17:57:11
    依赖项属性在WPF界面中扮演着核心角色,是WPF很多重要功能的基础,从原理上讲,它劫持了windows窗口的消息循环,使得窗口能实时应对属性变化进行重绘,并且从一个属性影响到其他属性 一。注册依赖项 1.定义依赖项...
  • 路由事件

    2018-08-15 00:16:00
    原文:路由事件简介:每个.NET开发人员都熟悉"事件"的思想,当有意义的事情发生时,由对象(WPF元素)发送的用于通知代码的消息WPF通过路由(event routing)的概念增强了.Net事件模型,事件路由允许源自某个元素的...

空空如也

空空如也

1 2 3
收藏数 41
精华内容 16
关键字:

wpf消息注册