我正在尝试在我的代码后面创建一个用户控件,然后响应该控件中的事件。可能是因为编译时控件不存在,Visual Studio无法编译我创建的处理程序子例程来捕获我的控件事件。重要的是,我想在运行时决定控件的类型(这就是为什么我不只是硬编码)。
[在继续之前,控件正常工作,包括事件和事件处理程序,当以“正常”方式在XAML中创建控件时使用。我想在代码后面创建控件实例,这样我就可以避免重复99%相同的页面了
这“有效”(但不能给我灵活性):
Public WithEvents AnswerPanel As MyControls.ScrollerControl
...(以及New()子中的初始化):
AnswerPanel = New MyControls.ScrollerControl
ItemStack3.Children.Add(AnswerPanel)
AddHandler AnswerPanel.GuessMade, AddressOf CheckAnswer
...(这是响应ScrollerControl中自定义事件的处理程序)
Public Sub CheckAnswer(answer As String) Handles AnswerPanel.GuessMade
使用上面的代码,一切都按预期工作:控件在运行时创建,其事件处理正确。
我想要实现的是当我初始化我的控件时能够选择不同的用户控件(例如ScrollerControl2,ScrollerControl3等)我可以通过更改第一个来创建控件行到:
Public WithEvents AnswerPanel As UserControl
但是一旦做出改变,我就不能再在我的处理程序中引用自定义事件了(推测)编译器将其视为通用UserControl,它不包括我的自定义GuessMade事件。事件名称上的编译器错误并告诉我它不存在。
我确定我在这里做错了什么。我认为这是一个理论/概念问题,而不是我的代码。
我是在正确的轨道上还是以错误的方式解决这个问题?
答案 0 :(得分:1)
如果我正在读这个权利,你有一个用户控件可以触发一个事件,你希望父页面能够捕获它吗?如果是这样,您需要引发事件,这将导致事件冒泡到父级。 IE:
Partial Class user_controls_myControl
Inherits System.Web.UI.UserControl
Public Event DataChange As EventHandler
End Class
这将使用名为DataChange的公共事件创建一个控件。现在,如果您查看实例化用户控件的父页面中的代码,您将看到它有一个名为" OnDataChange"的事件。就像onCLick事件一样,您可以在父页面中为此分配一个方法。现在,您只需要在用户控件中引发事件。这可以在控件中添加,例如按钮单击或单选按钮更改事件:
RaiseEvent DataChange(Me, New EventArgs)
这需要两个对象,即sender和event参数。通常我通过ME,这是用户控件。这很好,因为您可以使用反射来获取所有控件的公共属性。您还可以使用它将对象强制转换为控件类型。我很少传递事件参数,但你当然可以。
我在这里回答了类似的问题:Handling events of usercontrols within listview
如果这不是您的想法,请告诉我
编辑:动态添加用户控件并附加事件:
首先,在将使用该控件的页面中,您需要添加一个占位符:
<asp:PlaceHolder ID="placeholder1" runat="server"></asp:PlaceHolder>
以及对页面开头的用户控件的引用(取决于页面的设置方式,您可能不需要这个。如果您收到页面指令错误,请将其删除):
<%@ Reference="" Control="~/user_controls/myControl.ascx"%>
在父页面中,您可以创建用户控件并将其添加到占位符。您必须使用以下事件声明用户控件:
Private WithEvents myNewControl As New user_controls_myControl
然后,在某些方法中,您可以将其添加到页面中,如下所示:
Dim getPh As New PlaceHolder
'create an instance of the user control
newMyControl = CType(LoadControl("~/user_controls/myControl.ascx"), user_controls_myControl)
'get a handle on the place holder
getPh = me.placeHolder1
'add the user control to the place holder
getPh.Controls.Add(newMyControl)
然后,确保你有事件方法:
Protected Sub myEvent(ByVal sender As Object, ByVal e As EventArgs) Handles myNewControl.DataChange
End Sub
所以,如果你像我之前建议的那样将RaiseEvent添加到用户控件中,这应该适合你。
答案 1 :(得分:0)
我现在有一个答案。我怀疑我是从错误的角度思考这个问题。
简而言之,我试图从我的用户控件中引发一个事件,但我需要在基类中引发事件并从我的用户控件中调用它。
所以我的基类(我的用户控件继承自),现在包含以下内容:
Public Event GuessMade(answer As String)
Protected Sub RaiseGuessEvent(answer As String)
RaiseEvent GuessMade(answer)
End Sub
然后,在我的用户控件中,当我需要引发事件时,我只需像这样调用RaiseGuessEvent子:
Me.RaiseGuessEvent(CurrentValue)
另外,我当然必须从子类/用户控件中删除该事件。