• WPF 截图工具


    上周需要再产品上编写一个截图工具,发现博客上的文章都是只有截取屏幕这一步,或是需要关注公众号之类的营销,便自己撸了一个,今天在github上发现了一个开源的框架,如果准备开始写的可以参照那个框架。

    https://github.com/WPFDevelopersOrg/WPFDevelopers

    刚刚写完便记录一下自己遇到的问题,防止后面忘掉。

    在渲染canvas的时候报错:System.ArgumentException:“值不在预期的范围内。”

     var renderTargetBitmap = new RenderTargetBitmap(Convert.ToInt32(_AllScreenWidth),
                    Convert.ToInt32(_AllScreenHeight), 96d, 96d, PixelFormats.Default);
                renderTargetBitmap.Render(Capture_Canvas);
    
    
                var targetRec = new Int32Rect((int)rect.X, (int)rect.Y, (int)rect.Width , (int)rect.Height );
    
                var img = new CroppedBitmap(renderTargetBitmap,
                    targetRec);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这里我原来按照用户框的举行设置渲染范围发现报错,修改targetRec的X,Y后可以显示图片,确认应该是裁剪范围的原因,修改为整个屏幕渲染解决问题

    报错原因应该是剪切范围与渲染范围一致导致的报错,应该保证原图大于剪切区域。

    取消EventHanlder上面挂载的所有事件

    How would it be possible to remove all event handlers of the ‘Click’ event of a ‘Button’?

    先说一下,我这一步其实绕了远路增加了程序的冗余性,应该是创建一个工厂模式,用户点击按钮时按照性质唤醒不同的函数,这种可参照上面的框架地址。

    才开始是因为截图下面创建了四个按钮,分别是箭头,矩形,文字和保存,但是唤醒箭头功能后,再次点击矩形两个都会,但是他们点击的顺序是不一致的,所以我打算每次点击事件按钮就取消掉挂载在``MouseDown,MouseUp,MouseMove的所有事件,在重新挂载到此按钮事件,所以有了上面这个需求。
    搜索后发现需要反射方法调用MouseDownEventHandler里面的removeHanlder方法,这个可以在元数据中看到具体的数据,但是目前有的解决方案全是针对Winform的,不适用于WPF。

    这是Winform control

    /// 
            /// 清除一个对象的某个事件所挂钩的delegate
            /// 
            /// 控件对象
            /// 事件名称,默认的
            public static void ClearEvents(this object ctrl, string eventName = "_EventAll")
            {
                if (ctrl == null) return;
    
                BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Static;
                EventInfo[] events = ctrl.GetType().GetEvents(bindingFlags);
    
    
                if (events == null || events.Length < 1) return;
    
                for (int i = 0; i < events.Length; i++)
                {
    
                    EventInfo ei = events[i];
                    //只删除指定的方法,默认是_EventAll,前面加_是为了和系统的区分,防以后雷同
                    if (eventName != "_EventAll" && ei.Name != eventName) continue;
    
    
    
                    /********************************************************
                     * class的每个event都对应了一个同名(变了,前面加了Event前缀)的private的delegate类
                     * 型成员变量(这点可以用Reflector证实)。因为private成
                     * 员变量无法在基类中进行修改,所以为了能够拿到base 
                     * class中声明的事件,要从EventInfo的DeclaringType来获取
                     * event对应的成员变量的FieldInfo并进行修改
                     ********************************************************/
    
                    var fileds = ei.DeclaringType.GetFields(bindingFlags);
                    foreach (var filed in fileds)
                    {
                        if (filed.Name.Equals("MouseDownEvent"))
                        {
                            filed.SetValue(ctrl, null);
                            var mEvent = filed.GetValue(ctrl);
                            var remove = filed.FieldHandle;
    
                        }
                        if (filed.Name.Equals("MouseMoveEvent"))
                            filed.SetValue(ctrl, null);
                        if (filed.Name.Equals("MouseUpEvent"))
                            filed.SetValue(ctrl, null);
                    }
                }
                
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    这是WPF UIelement

    /// 
            /// Removes all event handlers subscribed to the specified routed event from the specified element.
            /// 
            /// The UI element on which the routed event is defined.
            /// The routed event for which to remove the event handlers.
            public static void RemoveRoutedEventHandlers(UIElement element, RoutedEvent routedEvent)
            {
                // Get the EventHandlersStore instance which holds event handlers for the specified element.
                // The EventHandlersStore class is declared as internal.
                var eventHandlersStoreProperty = typeof(UIElement).GetProperty(
                    "EventHandlersStore", BindingFlags.Instance | BindingFlags.NonPublic);
                object eventHandlersStore = eventHandlersStoreProperty.GetValue(element, null);
    
                // If no event handlers are subscribed, eventHandlersStore will be null.
                // Credit: https://stackoverflow.com/a/16392387/1149773
                if (eventHandlersStore == null)
                    return;
    
                // Invoke the GetRoutedEventHandlers method on the EventHandlersStore instance 
                // for getting an array of the subscribed event handlers.
                var getRoutedEventHandlers = eventHandlersStore.GetType().GetMethod(
                    "GetRoutedEventHandlers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                var routedEventHandlers = (RoutedEventHandlerInfo[])getRoutedEventHandlers.Invoke(
                    eventHandlersStore, new object[] { routedEvent });
    
                if (routedEventHandlers == null)
                    return;
    
                // Iteratively remove all routed event handlers from the element.
                foreach (var routedEventHandler in routedEventHandlers)
                    element.RemoveHandler(routedEvent, routedEventHandler.Handler);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    箭头样式

    箭头样式也是从github上面找的框架,直接地址po上来吧

    https://github.com/icsharpcode/WpfDesigner

  • 相关阅读:
    Zongmu AVM车载环视 Android SDK 简介
    《高质量的C/C++编程规范》学习
    [项目管理-3]:软硬件项目管理 - 范围管理(空间)
    ubuntu虚拟机中安装Hadoop全过程(单机分布方式+伪分布方式)
    速盾:服务器cdn加速超时如何解决?
    时序分解 | MATLAB实现ICEEMDAN+SE改进的自适应经验模态分解+样本熵重构分量
    SpringBoot 整合 RabbitMQ 实现消息回调、手动确认 (二) 有图 有源码
    JAVA基础(三十六)——常用类之StringBuffer类和StringBuilder类
    【老生谈算法】matlab实现数字图像复原算法源码——数字图像复原算法
    数据结构与算法(一)线性结构篇
  • 原文地址:https://blog.csdn.net/qq_41059339/article/details/126559445