2

我在这里寻找一些指导。

在我的网站上,我将内容放在 Web 用户控件中。例如,我将有一个 NewsItem 控件、一个 Article 控件、一个 ContactForm 控件。

这些将出现在我网站的各个地方。

我正在寻找的是一种让这些控件将消息传递到它们所在的页面的方法。

我不想将它们紧密耦合,所以我认为我将不得不通过事件/代表来做到这一点。不过,我有点不清楚我将如何实现这一点。

几个例子:

1

已提交联系表格。提交后,我不想用“您的邮件已发送”来限制该消息的放置,而是用状态消息和可能的建议行为通知页面控件已打开。因此,一条消息将包括要呈现的文本以及enum类似DisplayAs.PopupDisplayAs.Success

2

文章控件在数据库中查询文章对象。数据库返回异常。自定义异常与DisplayAs.Error枚举一起传递给页面。该页面处理此错误并在错误出现的任何地方显示它。

我正在尝试完成类似于 ValidationSummary 控件的操作,但我希望页面能够在枚举感觉合适时显示消息。

同样,我不想紧密绑定或依赖页面上存在的控件。我希望控件引发这些事件,但如果需要,页面可以忽略它们。

我会以正确的方式解决这个问题吗?

我想要一个code样本来帮助我入门。

我知道这是一个更复杂的问题,所以我会在投票/选择答案之前等待更长时间。

4

3 回答 3

2

以下假设您知道您的控件都放置在类型的页面上App.YourPage

这是我放置在 MasterPage 或 Page 上的快速消息框,只需从任何页面或控件调用。(对不起,它在 VB.net 中不是 c#)

您可以扩展 AddMessage 以记录并执行其他基于事务的操作(我从中提取了我们的控制器逻辑)

从任何控制:

CType(Page, App.YourPage).messageBox.AddMessage(
         ctrlMessageBox.MessageTypes.InfoMessage
          ,"Updated Successfully")

控制:

    Public Class ctrlMessageBox
        Inherits System.Web.UI.UserControl

        'List of types that a message could be
        Enum MessageTypes
            InfoMessage
            ErrorMessage
            WarningMessage
        End Enum

#Region "[Message] inner class for structered message object"
        Public Class Message
            Private _messageText As String
            Private _messageType As MessageTypes
            Public Property MessageText() As String
                Get
                    Return _messageText
                End Get
                Set(ByVal value As String)
                    _messageText = value
                End Set
            End Property
            Public Property MessageType() As MessageTypes
                Get
                    Return _messageType
                End Get
                Set(ByVal value As MessageTypes)
                    _messageType = value
                End Set
            End Property

        End Class
#End Region

        'storage of all message objects
        Private _messages As New List(Of Message)

        'Creates a Message object and adds it to the collection
        Public Sub addMessage(ByVal MessageType As MessageTypes, ByVal MessageText As String)
            Page.Trace.Warn(Me.GetType.Name, String.Format("addMessage({0},{1})", MessageType.ToString, MessageText))
            Dim msg As New Message
            msg.MessageText = MessageText
            msg.MessageType = MessageType
            _messages.Add(msg)
        End Sub

        Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
            ' Page.Trace.Warn(Me.GetType.Name, String.Format("Page_PreRender(_messages.Count={0})", _messages.Count))

        End Sub
        Public Overrides Sub RenderControl(ByVal writer As System.Web.UI.HtmlTextWriter)
            Page.Trace.Warn(Me.GetType.Name, String.Format("ctrlMessageBox.RenderControl(_messages.Count={0})", _messages.Count))
            'draws the message box on the page with all messages

            If _messages.Count = 0 Then Return
            Dim sbHTML As New StringBuilder
            sbHTML.Append("<div id='MessageBox'>")

            For Each msg As Message In _messages
                sbHTML.AppendFormat("<p><img src='{0}'> {1}</p>", getImage(msg.MessageType), msg.MessageText)
            Next

            sbHTML.Append("</div>")

            writer.Write(sbHTML.ToString)

            'dim ctrlLiteral As New Literal()
            'ctrlLiteral.Text = sbHTML.ToString
            'Me.Controls.Add(ctrlLiteral)
        End Sub

        'returns a specific image based on the message type
        Protected Function getImage(ByVal type As MessageTypes) As String
            Select Case type
                Case MessageTypes.ErrorMessage
                    Return Page.ResolveUrl("~/images/icons/error.gif")
                Case MessageTypes.InfoMessage
                    Return Page.ResolveUrl("~/images/icons/icon-status-info.gif")
                Case MessageTypes.WarningMessage
                    Return Page.ResolveUrl("~/images/icons/icon-exclaim.gif")
                Case Else
                    Return ""
            End Select
        End Function
    End Class
于 2010-05-07T18:25:03.127 回答
2

您可以将子页面中发生的事件冒泡到父页面。父页面可以注册该事件并使用它(如果它有用的话)。

父 ASPX

<uc1:ChildControl runat="server" ID="cc1" OnSomeEvent="cc1_SomeEvent" />

父 c#

protected void cc1_SomeEvent(object sender, EventArgs e)
{
    // Handler event
}

孩子 C#

public event EventHandler OnSomeEvent;

protected void ErrorOccurInControl()
{
     if (this.OnSomeEvent != null)
     {
          this.OnSomeEvent(this, new EventArgs());
     }
}

protected override void OnLoad(EventArgs e)
{
     ErrorOccurInControl();
}
于 2010-05-07T19:14:06.290 回答
1

数据注释验证器非常适合这类事情。通常它们在 ASP.NET MVC 中使用,但它们在 WebForms 中工作得很好。您可以使用内置验证器或创建自己的自定义验证器来执行更复杂的验证。

此示例在 VB.NET 中,但您应该不难看到其价值:

http://adventuresdotnet.blogspot.com/2009/08/aspnet-webforms-validation-with-data.html

http://blogs.microsoft.co.il/blogs/gilf/archive/2010/04/08/building-asp-net-validator-using-data-annotations.aspx

于 2010-05-07T20:16:51.657 回答