如何在该窗口中填充的控件中引发事件时在一个窗口中处理事件? [英] How do i handle an event in one window while raising the event in a control populated in that window?

查看:69
本文介绍了如何在该窗口中填充的控件中引发事件时在一个窗口中处理事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试处理应用程序主窗体中的事件,其中所述事件是从主窗体上填充的用户控件引发的。我已经为主表单和用户控件中实现的事件定义了一个接口。我正在使用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 实例会调用您想要通过窗口代码处理的一些事件;它们可以由用户的输入动作直接调用,例如,通过鼠标或键盘。您的窗口代码无法访问此事件,但它无法访问。因此,您必须执行以下操作:

  1. 创建自定义控件类的全新事件实例。我可能需要一个全新的事件参数类,一个派生自 System.EventArgs 的类;比方说,您将此类型命名为 MyEventArgs
  2. 将此事件实例公开给窗口。也就是说,将它设为 public ,但更好的是内部。假设这个实例成员名为 OnMyInnerControlClicked c>。
  3. 现在,假设您希望在用户单击某些内部控件时调用此实例,自定义控件的直接或间接子项。然后为你的内部控件添加一个永久事件处理程序。
  4. 在上一项中提到的偶数处理程序中,首先检查你的 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 some UIElement 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:

  1. 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 type MyEventArgs
  2. Expose this event instance to the window. That is, make it public, but better internal. Let's say, this instance member is called OnMyInnerControlClicked.
  3. 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).
  4. In your even handler mentioned in the previous item, first check up that your OnMyInnerControlClicked instance is not Nothing. If not, invoke it using OnMyInnerControlClicked.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆