如何在WPF中为用户控件创建用户定义(新)事件?一个小示例
我有一个如何在WPF中为用户控件创建用户定义(新)事件?一个小示例,wpf,events,user-controls,Wpf,Events,User Controls,我有一个UserControl,在其中我使用了一个Canvas,在该Canvas中有一个矩形。我想为该用户控件(画布和矩形)创建一个单击事件,然后在主窗口中使用该事件 问题是:我想为UserControl创建一个新的单击事件。怎么做?请给出一些示例或代码。关于如何从主窗口可以注册的UserControl中公开事件的简短示例: 在用户控件中: 一,。添加以下声明: public event EventHandler UserControlClicked; 二,。在用户控件中,单击事件,如下所示:
UserControl
,在其中我使用了一个Canvas
,在该Canvas中有一个矩形。我想为该用户控件(画布和矩形)创建一个单击事件,然后在主窗口中使用该事件
问题是:我想为
UserControl
创建一个新的单击事件。怎么做?请给出一些示例或代码。关于如何从主窗口可以注册的UserControl中公开事件的简短示例:
在用户控件中:
一,。添加以下声明:
public event EventHandler UserControlClicked;
二,。在用户控件中,单击事件,如下所示:
private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
{
if (UserControlClicked != null)
{
UserControlClicked(this, EventArgs.Empty);
}
}
在主窗口中:
用户控件现在将有一个UserControlClicked
事件,您可以注册到:
<local:UserControl1 x:Name="UC" UserControlClicked="UC_OnUserControlClicked" />
我发现将值传递给处理程序更容易:
public event Action<string> onUserCodeFetched;
private void btnEnterClicked(object sender, RoutedEventArgs e)
{
onUserCodeFetched(PersonellCode.Text);
PersonellCode.Text = "";
}
公共事件操作onUserCodeFetched;
私有void bEnterClick(对象发送方,路由目标)
{
onUserCodeFetched(PersonellCode.Text);
PersonellCode.Text=“”;
}
这是一个老问题,但我发现使用中的自定义事件之类的属性绕过事件也很有用。您可以使用常规事件处理程序,也可以使用更具体的事件处理程序(RoutedEventHandler、MouseButtonEventHandler等),以避免以后的强制转换。例如,要绕过单击事件,可以在自定义控件类中编写:
public readonly object objectLock=new object();
公共事件路由EventHandler自定义单击
{
添加{lock(objectLock){myClickableInnerControl.Click+=value;}}
删除{lock(objectLock){myClickableInnerControl.Click-=value;}}
}
对于PreviewMouseDown事件,它将类似于:
public readonly object objectLock=new object();
公共事件鼠标按钮Venthandler CustomPreviewMouseDown
{
添加{lock(objectLock){myInnerControl.PreviewMouseDown+=value;}}
移除{lock(objectLock){myInnerControl.PreviewMouseDown-=value;}}
}
在这种情况下,myInnerControl将是您的画布
然后,您可以将xaml中的事件初始化为
或
从代码背后:
点击Ctrl1.CustomClick+=点击Ctrl1\u CustomClick;
或
CustomCtrl1.CustomPreviewMouseDown+=CustomCtrl1\u CustomPreviewMouseDown;
您还可以订阅几个内部控件事件的回调(当它们重叠时要小心,因为previewMouseDown等事件不仅由前面的控件触发,而且也由下面的控件触发)
public readonly object objectLock=new object();
公共事件鼠标按钮Venthandler CustomPreviewMouseDown
{
添加{lock(objectLock)
{
myInnerControl1.PreviewMouseDown+=值;
myInnerControl2.PreviewMouseDown+=值;
}}
移除{lock(objectLock)
{
myInnerControl1.PreviewMouseDown-=值;
myInnerControl2.PreviewMouseDown-=值;
}}
}
(如果内部控件部分重叠,可以在回调方法中使用相应的eventArgs Handled属性以避免重复)
最后,您可以向内部控件触发的事件添加一层控件:
bool MousePreviewDownUsed=false;
事件鼠标按钮Venthandler _myPreviewMouseDownEvent=null;
公共事件鼠标按钮Venthandler CustomPreviewMouseDown
{
添加
{
锁(对象锁)
{
_myPreviewMouseDownEvent+=值;
if(值!=null&!MousePreviewDownUsed)
{
myInnerControl.PreviewMouseDown+=myInnerControl\u PreviewMouseDown;
MousePreviewDownUsed=true;
}
}
}
去除
{
锁(对象锁)
{
如果(_myPreviewMouseDownEvent!=null)
{
_myPreviewMouseDownEvent-=值;
如果(_myPreviewMouseDownEvent==null ||
_myPreviewMouseDownEvent.GetInvocationList().Length==0)
&&鼠标预览(已使用)
{
_myPreviewMouseDownEvent=null;
myInnerControl.PreviewMouseDown-=myInnerControl\u PreviewMouseDown;
MousePreviewDownUsed=false;
}
}
}
}
}
私有void myInnerControl_PreviewMouseDown(对象发送器,鼠标按钮Ventargs e)
{
//执行一些以前的操作或控制是否必须广播事件
_myPreviewMouseDownEvent?.Invoke(发送方,e);
}
此事件是以与以前相同的方式从xaml或代码后面初始化的。这个问题不是很清楚。也许你可以重新措辞以澄清你的问题?你需要取消注册吗?为了完整起见,
UserControl\u MouseDown
事件还需要与XAML中实际的MouseDown
事件绑定,显然这样做是可行的。我无法让它起作用。它告诉我UserControlClicked不可访问或无法识别。@zar另一种可能是重写当前的OnMouseDown处理程序protected override void OnMouseDown(MouseButtonEvent