如何在该窗口中填充的控件中引发事件时在一个窗口中处理事件? [英] How do i handle an event in one window while raising the event in a control populated in that window?
问题描述
我正在尝试处理应用程序主窗体中的事件,其中所述事件是从主窗体上填充的用户控件引发的。我已经为主表单和用户控件中实现的事件定义了一个接口。我正在使用GalaSoft的MvvmLight获得MVVM支持。
后面的主要表单代码表示事件是附加的,但当我检查用户控件时,它表示没有附加到事件的处理程序,所以很明显,它不会到达处理程序。
任何帮助将不胜感激。
我定义的界面非常基本。
公开 接口 IEventFiring
事件 EventFiring(发件人作为 对象)
结束 界面
My Main Form Xaml如下所示:
< window x:class =MainWindowxmlns:x =#unknown>
xmlns = http://schemas.microsoft.com/w infx / 2006 / xaml / presentation
xmlns:x =http://schemas.microsoft.com/winfx/2006/xaml
xmlns:local = clr-namespace:EventFiringFromContolToMainForm
xmlns:efc =clr-namespace:EventFiringControl; assembly = EventFiringControl
Title =MainWindow>
< window.datacontext>
< local:mainwindowviewmodel xmlns:local =#unknown>
< stackpanel> ;
< textbox text ={Binding StatusText,Mode = OneWay}>
身高=25
保证金= 5/>
< separator margin =5>
< efc:usercontrol1 xmlns:efc =#unknown>
背后的代码是:
< span class =code-keyword>类 MainWindow
公共 Sub 新()
' 此调用是设计师所必需的。
InitializeComponent()
' 添加任何初始化后的InitializeComponent()调用。
RemoveHandler CType (DataContext, MainWindowViewModel).EventFiring, AddressOf EventFiringSub
AddHandler CType (DataContext,MainWindowViewModel).EventFiring, AddressOf EventFiringSub
CType (DataContext,MainWindowViewModel).StatusText = 附加到EventFiringSub的事件
结束 Sub
私有 Sub EventFiringSub()
CType (DataContext,MainWindowViewModel).StatusText = 已触发事件
结束 Sub
结束 班级
主窗体的viewmodel是:
Imports EventFiringControl
Imports GalaSoft.MvvmLight
Public 类 MainWindowViewModel
继承 ViewModelBase
Implements IEventFiring
私有 _statusText 作为 字符串
公共 属性 StatusText 作为 字符串
获取
返回 _statusText
结束 获取
设置 (value As String )
_statusText = value
RaisePropertyChanged(功能()StatusText)
结束 设置
结束 属性
公共 事件 EventFiring(发件人作为 对象) Implements IEventFiring.EventFiring
结束 类
我的控件应该抛出要在主窗体中处理的事件如下:
< usercontrol x:class =UserControl1xmlns:x =#unknown>
xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x =http://schemas.microsoft.com/winfx/2006/xaml
xmlns:mc =http://schemas.openxmlformats.org / markup-compatibility / 2006
xmlns:d =http://schemas.microsoft.com/expression/blend/2008
xmlns:local =clr -namespace:EventFiringControl
mc:Ignorable =d
d:DesignHeight =300d:DesignWid th =300>
< usercontrol.datacontext>
< local:eventfiringviewmodel xmlns:local =#unknown>
< grid>
< Button Content =CancelCommand ={Binding CancelCommand}Height =50/>
背后的代码是:
< pre lang =vb> 公共 类 UserControl1
公开 Sub 新()
' 此调用是设计者所必需的。
InitializeComponent()
< span class =code-comment>' 在InitializeComponent()调用后添加任何初始化。
结束 Sub
结束 类
最后,控件的视图模型如下:
Imports GalaSoft.MvvmLight.Command
Imports GalaSoft.MvvmLight
公共 类 EventFiringViewModel
继承 ViewModelBase
Implements IEventFiring
公共 ReadOnly 属性 CancelCommand 作为 RelayCommand
获取
返回 新 RelayCommand( Sub ()Ca ncelSub())
结束 获取
结束 属性
公开 Sub 新()
结束 Sub
私有 Sub CancelSub ()
RaiseEvent EventFiring( Me )
结束 Sub
公开 事件 EventFiring(发件人作为 对象) Implements IEventFiring.EventFiring
结束 班级
当我举起event EventFiring,后面的主窗口代码中的事件未被处理。
如有任何关于如何纠正我的问题的建议将不胜感激。
什么我试过了:
我试过没有成功实现界面。我也打算尝试创建一个单独的类,但是在线的例子不是很清楚。
我不明白问题出在哪里。为什么这个界面。如果在某个控件中调用了偶数,则必须将其暴露给需要处理此事件的代码。
有可能(最常见的问题) ,用户控件中的一些UIElement
实例会调用您想要通过窗口代码处理的一些事件;它们可以由用户的输入动作直接调用,例如,通过鼠标或键盘。您的窗口代码无法访问此事件,但它无法访问。因此,您必须执行以下操作:
- 创建自定义控件类的全新事件实例。我可能需要一个全新的事件参数类,一个派生自
System.EventArgs
的类;比方说,您将此类型命名为MyEventArgs
- 将此事件实例公开给窗口。也就是说,将它设为
public
,但更好的是内部
。假设这个实例成员名为OnMyInnerControlClicked $ c> c>。
- 现在,假设您希望在用户单击某些内部控件时调用此实例,自定义控件的直接或间接子项。然后为你的内部控件添加一个永久事件处理程序。
- 在上一项中提到的偶数处理程序中,首先检查你的
OnMyInnerControlClicked
实例不是Nothing
。如果没有,请使用OnMyInnerControlClicked.Invoke(self,New MyEventArgs())
调用它;另请参阅
EventHandler Delegate(系统) [ ^ ]。
如果您的问题不同而且这不是您所需要的,请澄清一下。我的描述假定您知道创建事件的常用技术,而不仅仅是处理它们。如果你有问题,请澄清一下。
-SA
I am attempting to handle an event in the application main form where said event is being raised from a user control populated on the main form. I've defined an Interface for the event which is being implemented in both the Main Form and the User Control. I'm using MvvmLight from GalaSoft for the MVVM support.
The main form code behind indicates that the event is attached, but when I do the check in the user control, it indicates that there is no handler attached to the event, so obviously, it won't ever get to the handler.
Any help would be appreciated.
The interface I've defined is pretty basic.
Public Interface IEventFiring
Event EventFiring(sender As Object)
End Interface
My Main Form Xaml looks like this:
<window x:class="MainWindow" xmlns:x="#unknown">
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:EventFiringFromContolToMainForm"
xmlns:efc="clr-namespace:EventFiringControl;assembly=EventFiringControl"
Title="MainWindow">
<window.datacontext>
<local:mainwindowviewmodel xmlns:local="#unknown">
<stackpanel>
<textbox text="{Binding StatusText, Mode=OneWay}">
Height="25"
Margin="5"/>
<separator margin="5">
<efc:usercontrol1 xmlns:efc="#unknown">
The code behind is:
Class MainWindow
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
RemoveHandler CType(DataContext, MainWindowViewModel).EventFiring, AddressOf EventFiringSub
AddHandler CType(DataContext, MainWindowViewModel).EventFiring, AddressOf EventFiringSub
CType(DataContext, MainWindowViewModel).StatusText = "Event Attached to EventFiringSub"
End Sub
Private Sub EventFiringSub()
CType(DataContext, MainWindowViewModel).StatusText = "Event Fired"
End Sub
End Class
The viewmodel for the main form is:
Imports EventFiringControl
Imports GalaSoft.MvvmLight
Public Class MainWindowViewModel
Inherits ViewModelBase
Implements IEventFiring
Private _statusText As String
Public Property StatusText As String
Get
Return _statusText
End Get
Set(value As String)
_statusText = value
RaisePropertyChanged(Function() StatusText)
End Set
End Property
Public Event EventFiring(sender As Object) Implements IEventFiring.EventFiring
End Class
My control which is supposed to throw the event to be handled in the main form is as follows:
<usercontrol x:class="UserControl1" xmlns:x="#unknown">
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:EventFiringControl"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<usercontrol.datacontext>
<local:eventfiringviewmodel xmlns:local="#unknown">
<grid>
<Button Content="Cancel" Command="{Binding CancelCommand}" Height="50"/>
The code behind is:
Public Class UserControl1
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
End Class
Finally, the view model for the control is as follows:
Imports GalaSoft.MvvmLight.Command
Imports GalaSoft.MvvmLight
Public Class EventFiringViewModel
Inherits ViewModelBase
Implements IEventFiring
Public ReadOnly Property CancelCommand As RelayCommand
Get
Return New RelayCommand(Sub() CancelSub())
End Get
End Property
Public Sub New()
End Sub
Private Sub CancelSub()
RaiseEvent EventFiring(Me)
End Sub
Public Event EventFiring(sender As Object) Implements IEventFiring.EventFiring
End Class
When I raise the event EventFiring, the event in the main window code behind is not handled.
Any suggestions as to how to correct my issue would be much appreciated.
What I have tried:
I've tried not implementing the interface without success. I'm also going to try creating a separate class, but the examples on line are not very clear.
I don't understand where the problem is. Why this interface. If you have an even invoked in some control, you have to expose it to the code which needs to handle this event.
It is possible (the most usual problem), that someUIElement
instances inside you user control invoke some events you want to handle by the code of your window; they may be invoked by the user's input action directly, say, by a mouse or a keyboard. Your window's code has no access to this event, and it cannot. So, you have to do the following:
- Create a brand-new event instance of your custom control class. I may require a brand-new event argument class, a class derived from
System.EventArgs
; let's say, you name this typeMyEventArgs
- Expose this event instance to the window. That is, make it
public
, but betterinternal
. Let's say, this instance member is calledOnMyInnerControlClicked
.- Now, let's say you want this even to be invoked when a user clicks some of your inner control, direct or indirect child of your custom control. Then add a permanent event handler to your inner control(s).
- In your even handler mentioned in the previous item, first check up that your
OnMyInnerControlClicked
instance is notNothing
. If not, invoke it usingOnMyInnerControlClicked.Invoke(self, New MyEventArgs())
; see also
EventHandler Delegate (System)[^].
If your problem is different and this is not what you need, please clarify that. My description assumes that you know the usual techniques of creating events, not only handling them. If you have problems with that, please clarify that, too.
—SA
这篇关于如何在该窗口中填充的控件中引发事件时在一个窗口中处理事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!