在代码后面创建的用户控件中的访问事件?

时间:2013-03-25 14:06:28

标签: vb.net windows-phone-7 xaml user-controls

我正在尝试在我的代码后面创建一个用户控件,然后响应该控件中的事件。可能是因为编译时控件不存在,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事件。事件名称上的编译器错误并告诉我它不存在。

我确定我在这里做错了什么。我认为这是一个理论/概念问题,而不是我的代码。

我是在正确的轨道上还是以错误的方式解决这个问题?

2 个答案:

答案 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)

另外,我当然必须从子类/用户控件中删除该事件。