c# 为自定义控件添加鼠标双击事件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# 为自定义控件添加鼠标双击事件相关的知识,希望对你有一定的参考价值。
最近在用一个厂家提供的控件(c++写的),这个控件只可以响应鼠标右键事件(厂家提供的接口),但是不能响应鼠标双击事件,现在我想在这个控件上添加双击事件(在c#环境下),我该如何扩展这个类?谢谢!
厂家提供的控件都是封装好的,就算你扩展这个类也只能添加功能,不能直接响应双击事件。但是你可以拦截这个控件的双击消息。
以下代码可加在控件的父窗口(假设为Form1),并在Form1初始化后安装拦截挂钩。同样的方法也可屏蔽那控件的其它消息,如屏蔽它的右键事件。
private const int GWL_WNDPROC = -4;
private const int WM_LBUTTONDOWN=0x0201;
private const int WM_LBUTTONUP=0x0202;
private const int WM_LBUTTONDBLCLK=0x0203;//双击消息
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, MyWndProc wndProc);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr CallWindowProc(IntPtr wndProc, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
public delegate IntPtr MyWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
private IntPtr OldWndProc = IntPtr.Zero;
private MyWndProc Wpr = null;
private IntPtr MyControlWndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
switch (msg)
case WM_LBUTTONDBLCLK://拦截双击消息
/*在这里,你想干什么就干什么*/
.......................
.......................
return (IntPtr)0;
default:
return CallWindowProc(OldWndProc, hWnd, msg, wParam, lParam);
//假设那个控件变量名为 _thatControl
private void InitializeThatControl()
//初始化的时候安装消息拦截
this.Wpr = new MyWndProc(this.MyControlWndProc);
this.OldWndProc = SetWindowLong(_thatControl.Handle, GWL_WNDPROC, Wpr);
public Form1()
InitializeComponent();
InitializeThatControl();//加这句,在Form初始化后安装消息拦截
参考技术A 能看到源码么?
能看到的话继续用c++写
或者添加自定义控件继承这个控件,再重写OnDoubleClick事件 参考技术B 在源代码上加个事件 参考技术C 你没有源代码,怎么加?与提供厂家联系吧。
为自定义控件实现值访问器时,未从事件中的模型获取更新值
【中文标题】为自定义控件实现值访问器时,未从事件中的模型获取更新值【英文标题】:Not getting updated value from model in events when implementing value accessor for custom controls 【发布时间】:2016-09-12 13:35:33 【问题描述】:我正在关注下面的文章,我正在尝试在与 ngModel 和 ngControl 集成的 Angular 2 中实现自定义控件。
文章:http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel
但是我很难弄清楚在发出事件时如何获取更新的模型值。好像是在事件中使用更新前的模型。
这是一个带有示例的 plunker:
https://plnkr.co/edit/ixK6UxhhWZnkFyKfbgky
我做错了什么?
main.ts
import bootstrap from '@angular/platform-browser-dynamic';
import App from './app';
bootstrap(App, [])
.catch(err => console.error(err));
app.ts
import Component from '@angular/core'
import FORM_DIRECTIVES from "@angular/common";
import CustomInput from './custom-input.component'
@Component(
selector: 'my-app',
providers: [],
template: `
<form (ngSubmit)="onSave()" #demoForm="ngForm">
<div class="row info-row">
<span class="col-xs-12">
<p><span class="boldspan">Form data:</span>demoForm.value | json</p>
<p><span class="boldspan">Model data:</span> dataModel</p>
</span>
</div>
<custom-input ngControl="someValue" ref-input (onKeyDown)="onKeyDown(input)" [(ngModel)]="dataModel">Enter data:</custom-input>
</form>
`,
directives: [CustomInput, FORM_DIRECTIVES]
)
export class App
dataModel: string = '';
onKeyDown(event)
console.log(event._value);
console.log(this.dataModel);
custom-input.component.ts
import Component, Provider, forwardRef, Input, Output, EventEmitter from "@angular/core";
import ControlValueAccessor, NG_VALUE_ACCESSOR, CORE_DIRECTIVES from "@angular/common";
const noop = () => ;
const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR = new Provider(
NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInput),
multi: true
);
@Component(
selector: 'custom-input',
template: `
<div class="form-group">
<label><ng-content></ng-content>
<input class="form-control" [(ngModel)]="value" (keydown)="onKeyDownEvent($event)" (blur)="onTouched()">
</label>
</div>
`,
directives: [CORE_DIRECTIVES],
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
)
export class CustomInput implements ControlValueAccessor
@Output() onKeyDown: EventEmitter<any> = new EventEmitter();
//The internal data model
private _value: any = '';
//Placeholders for the callbacks
private _onTouchedCallback: (_:any) => void = noop;
private _onChangeCallback: (_:any) => void = noop;
//get accessor
get value(): any return this._value; ;
//set accessor including call the onchange callback
set value(v: any)
if (v !== this._value)
this._value = v;
this._onChangeCallback(v);
//Set touched on blur
onTouched()
this._onTouchedCallback();
//From ControlValueAccessor interface
writeValue(value: any)
this._value = value;
//From ControlValueAccessor interface
registerOnChange(fn: any)
this._onChangeCallback = fn;
//From ControlValueAccessor interface
registerOnTouched(fn: any)
this._onTouchedCallback = fn;
onKeyDownEvent(event)
this.onKeyDown.emit(event);
【问题讨论】:
【参考方案1】:我认为问题在于您将自定义输出和注册回调混合在一起。在这种情况下,不需要自定义输出。
您可以利用CustomInput
组件中的ngModelChange
事件来调用_onChangeCallback
回调:
@Component(
selector: 'custom-input',
template: `
<div class="form-group">
<label><ng-content></ng-content>
<input class="form-control" [(ngModel)]="value"
(ngModelChange)="onModelChange($event)"
(keydown)="onKeyDownEvent($event)"
(blur)="onTouched()">
</label>
</div>
`,
(...)
export class CustomInput implements ControlValueAccessor
(...)
onModelChange(value)
this.value = value;
this._onChangeCallback(value);
在这种情况下,不再需要您的 getter 和 setter。
您也可能对这篇文章感兴趣(“NgModel 兼容组件”部分):
http://restlet.com/blog/2016/02/17/implementing-angular2-forms-beyond-basics-part-2/【讨论】:
感谢您提供的信息。我不知道 ngModelChange 以及多么棒的文章。我已经尝试过你提出的建议,这里是一个新的plunkr,但奇怪的是,一旦我删除了 get 和 set,它就不再绑定初始值了。你说我把事情搞混了,但是如果不这样做,怎么可能在组件之外获取更新的模型呢?以上是关于c# 为自定义控件添加鼠标双击事件的主要内容,如果未能解决你的问题,请参考以下文章