Reputation: 15419
I'm looking for some guidance here.
On my site I put things in Web user controls. For example, I will have a NewsItem Control, an Article Control, a ContactForm control.
These will appear in various places on my site.
I don't want to tightly couple them, so I think I will have to do this with Events/Delegates. I'm a little unclear as to how I would implement this, though.
A couple of examples:
A contact form is submitted. After it's submitted, instead of replacing itself with a "Your mail has been sent" which limits the placement of that message, I'd like to just notify the page that the control is on with a Status message and perhaps a suggested behaviour. So, a message would include the text to render as well as an enum
like DisplayAs.Popup
or DisplayAs.Success
An Article Control queries the database for an Article object. Database returns an Exception. Custom Exception is passed to the page along with the DisplayAs.Error
enum. The page handles this error and displays it wherever the errors go.
I'm trying to accomplish something similar to the ValidationSummary Control, except that I want the page to be able to display the messages as the enum feels fit.
Again, I don't want to tightly bind or rely a control existing on the Page. I want the controls to raise these events, but the page can ignore them if it wants.
Am I going about this the right way?
I'd love a code
sample just to get me started.
I know this is a more involved question, so I'll wait longer before voting/choosing the answers.
Upvotes: 2
Views: 1029
Reputation: 21178
The data annotation validators are really good for this type of thing. Typically they are used within ASP.NET MVC, but they work just fine in WebForms. You can use the built-in validators or create your own custom ones that do more complex validations.
This example is in VB.NET, but it shouldn't be hard for you to see the value:
http://adventuresdotnet.blogspot.com/2009/08/aspnet-webforms-validation-with-data.html
Upvotes: 1
Reputation: 62260
You can bubble up the event occurs in child to parent page. Parent page can register that event and utilizes it (if it is useful).
Parent ASPX
<uc1:ChildControl runat="server" ID="cc1" OnSomeEvent="cc1_SomeEvent" />
Parent c#
protected void cc1_SomeEvent(object sender, EventArgs e)
{
// Handler event
}
Child C#
public event EventHandler OnSomeEvent;
protected void ErrorOccurInControl()
{
if (this.OnSomeEvent != null)
{
this.OnSomeEvent(this, new EventArgs());
}
}
protected override void OnLoad(EventArgs e)
{
ErrorOccurInControl();
}
Upvotes: 2
Reputation: 18215
The following is assuming you know that your controls are all placed on a page of type App.YourPage
Here's a quick message box that I place onto the MasterPage or Page and just call from any page or control. (Sorry its in VB.net not c#)
You can extend out AddMessage to log and do other transaction based action (I pulled out our controller logic from it)
from any control:
CType(Page, App.YourPage).messageBox.AddMessage(
ctrlMessageBox.MessageTypes.InfoMessage
,"Updated Successfully")
Control:
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
Upvotes: 2