我有一个充满页面和用户控件的应用程序,其中许多都有一个或多个标签控件,用于向用户显示各种不同的消息。
示例:通常在Company.aspx页面上使用的AddCompany.ascx用户控件(使用App.Master MasterPage)上面有一个名为“OutOfCreditLabel”的标签,文字=“错误:你因为你没有信誉,所以无法创建一家新公司“。代码检查信用额度并在需要时显示标签。
我想在所有地方摆脱所有这些标签,只是有一个我可以从任何地方调用的方法,如
ShowUserMessage("Text goes here");
在之前的项目中,我已将其作为主页面上的单个标签和.master.cs中的公共方法实现 - 只要页面有行
<%@ MasterType VirtualPath="~/App.master" %>
在其中,这有效 - 但我不能让它在用户控件(.ascx.cs)上工作。这有诀窍吗?
或者......有更好的方法吗?
对于可在网站中的任何位置使用的“全局”用户消息方法,您会推荐什么?
也许是任何不错的jQuery解决方案?
更新
RPM1984要求进一步澄清,所以我试图以不同的方式提出这个问题:
我需要一个可以从代码隐藏(页面或用户控件)调用的方法,然后将向用户显示我指定的任何文本,例如stackoverflow如何告诉您有关新内容的信息您下次访问该网站时的问题的答案。它可以在窗口的顶部(如SO)或页面的某个位置,无关紧要。重要的是它是一种“全局”方法,而不是在项目中的每个其他页面和用户控件上都有各种javascript警报和asp:label。
像这样的场景:
用户点击我页面上“widget manager”用户控件上的“Create Widget”按钮。在事件处理程序中:
if (User.IsOutOfCredit)
{
ShowUserMessage("Sorry, you cannot create widgets; you are out of credit.");
}
这会导致用户看到“抱歉,您无法创建小部件;您的信誉不足”。无论是在页面中的弹出页面还是红色文本中,或者像StackOverflow一样在顶部,一切都很好
这有意义吗?
答案 0 :(得分:2)
为什么不使用简单的HTML“老派”扩展方法? (即静态方法)
namespace Web.Helpers
{
public class HtmlHelpers
{
public static string Label(string target)
{
var dynamicText = SomeWhere.GetSomeCoolText();
return String.Format("<label for='{0}'>{1}</label>", target, dynamicText);
}
}
}
然后在你的HTML中:
<%= HtmlHelpers.Label("sometarget") =>
在主母版页中,只需导入命名空间:
<%@ Import Namespace="Web.Helpers" %>
问题更新后编辑
好的,我看到你现在要做的事情。我建议所有客户端都这样做。
也就是说,在您的主母版页中,创建一个具有唯一ID的最初隐藏的<div>
:
<div id="message" style="display: none"></div>
然后在Web项目的某处创建一个帮助器方法,渲染出一些脚本。
public void DisplayMessage()
{
string message = SomeWhere.GetSomeCoolText();
StringBuilder script = new StringBuilder();
script.AppendFormat("$('message').show().append("<span>{0}</span>")", message);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), script.ToString(), true);
}
当然,这只是一个指导原则。您不必使用jQuery,您不必在方法中对脚本进行硬编码。您可以创建一个接受字符串并修改div的HTML的JavaScript函数,然后只需调用该函数。
如果您需要特殊的服务器控制,国际化等,这完全取决于您的“消息”的复杂程度。
但这肯定是实现你想要的最简单方法(恕我直言)。
答案 1 :(得分:2)
就个人而言,我更喜欢将HttpContext.Current.Items字典与自定义控件一起使用。类似于Keith Bluestone的方法,但不需要在页面上任意命名控件;它清楚地说明了发生了什么。你可以很容易地将它打包成一个类作为服务器控件,但是这里是放入一个标准的web项目。
在您的代码中注册消息:
SiteMessageUtility.Add("Test message");
要在您的页面或母版页中显示,或者在任何地方显示:
<%@ Register TagPrefix="custom" TagName="SiteMessage" Src="~/Controls/SiteMessage.ascx" %>
<custom:SiteMessage runat="server" />
以下是您需要的文件:
〜\ App_Code文件\ SiteMessageUtility.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public static class SiteMessageUtility
{
public static void Add(string message)
{
string currMessage = HttpContext.Current.Items["message"] as string;
if (currMessage == null)
{
HttpContext.Current.Items["message"] = message;
}
else
{
HttpContext.Current.Items["message"] = currMessage + "<br/>" + message;
}
}
}
〜\控制\ SiteMessage.aspx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="SiteMessage.ascx.cs" Inherits="Controls_SiteMessage" %>
<asp:Literal runat="server" ID="message" />
〜\控制\ SiteMessage.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Controls_SiteMessage : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnPreRender(EventArgs e)
{
message.Text = (string)HttpContext.Current.Items["message"];
base.OnPreRender(e);
}
}
答案 2 :(得分:1)
在母版页上添加以下控件: hfMsg隐藏字段将保留将显示的消息 并且hfCtrl将保存将显示此消息的html控件的名称,该消息将在此示例中为lblMsg。
<label id="lblMsg" style="background-color:Yellow; border:solid 1px; width:200px;height:100px;display:none;"></label>
<asp:HiddenField ID="hfMsg" runat="server" />
<asp:HiddenField ID="hfCtrl" runat="server" />
注意:您可以在ASCX控件上添加另一个具有不同ID的html控件,并使用它来显示消息而不是lblMsg。
以及以下脚本:
<script language="javascript" type="text/javascript">
var msg = $('#<%= hfMsg.ClientID %>').attr("value");
var ctrl = $('#<%= hfCtrl.ClientID %>').attr("value");
if (msg != undefined && msg != "") {
$("#" + ctrl).html(msg);
$("#" + ctrl).show();
}
else {
$("#" + ctrl).hide();
}
</script>
注意:脚本只是检查hfMsg控件是否有要显示的消息。
并将以下两种方法添加到母版页:
public void ShowMessage(string control, string message)
{
this.hfCtrl.Value = control;
this.hfMsg.Value = message;
}
public void ClearMessage()
{
this.hfMsg.Value = string.Empty;
}
最后,您可以从任何类似的页面调用ShowMessage方法,以在母版页上显示消息:
Master.ShowMessage("lblMsg","hello world!");
如果您有一个包含html标签的用户控件(例如lblUserMsg)来显示该消息,您只需调用ShowMessage并将其传递给标签名称:
Master.ShowMessage("lblUserMsg","hello world!");
答案 3 :(得分:1)
我一直在寻找一种向用户显示消息的站点方式。我找到了jnotifica。它类似于页面顶部的stackoverflow栏。
目前作者的网站似乎已关闭。
答案 4 :(得分:1)
在MasterPage中使用SetStatus方法始终是我这样做的方式,从用户控件内部访问MasterPage,只需在usercontrol中创建一个私有属性(或者创建一个所有用户控件继承的baseControl类) ):
private TheNameSpaceOfMyMasterPage.MyMasterPage Master
{
get { return (TheNameSpaceOfMyMasterPage.MyMasterPage)Page.Master; }
}
protected void btnSave_OnClick(object sender, EventArgs e)
{
// Do your stuff...
// Set the Status
this.Master.ShowStatus("blah blah blah");
}
此外,如果您正在使用控件来保存状态消息,请记住在其上禁用ViewState,否则您将在不希望的回发之间获得相同的状态消息。
答案 5 :(得分:1)
一些好的答案,但是......
MGOwen 未提及任何特殊的DHTML要求(例如,从客户端更新)。那么为什么不像他提到的那样只实现一个简单的服务器端辅助方法,找到显示消息的目标控件,并显示它?
以下 ShowMessage 将在页面上的任何位置找到目标消息控件,并根据需要启用任何页面以覆盖默认应用程序的ShowMessage行为。
public static class ASPHelper {
// Defines something that shows a message
public interface IShowMessage
{
void ShowMessage(string msg);
}
// default implementation: finds a target message display control
// wherever it is on the page.
static void ShowMessage_Default(string msg)
{
const string SHOWMESSAGE_CONTROL_ID = "ctlShowMessage"; // or whatever
// find the control
Page currentPage = HttpContext.Current.CurrentHandler as Page;
Control ctlMessage = currentPage.FindControlRecursive(SHOWMESSAGE_CONTROL_ID);
if (ctlMessage == null)
throw new Exception("ShowMessage control not found!" );
Literal ctlMessageLiteral = ctlMessage as Literal;
if (ctlMessageLiteral == null)
throw new Exception("ShowMessage control must be a Literal!");
// Message control should not implement viewstate -- unneccesary
Debug.Assert(ctlMessageLiteral.EnableViewState == false);
// show it
ctlMessageLiteral.Text = msg;
ctlMessageLiteral.Visible = true;
}
// public version for use across app & in pages
static public void ShowMessage(string msg)
{
// Allow the current page to implement its own way of showing
// messages -- provides flexibility.
Page currentPage = HttpContext.Current.CurrentHandler as Page;
IShowMessage showMessageImpl = currentPage as IShowMessage;
if (showMessageImpl != null)
{
// Show using custom message displayer
showMessageImpl.ShowMessage(msg);
}
else
{
// static/global/default version
ShowMessage_Default(msg);
}
}
} // end ASPHelper
要使用,只需在页面上放置文字控件,如:
<div><asp:Literal
ID="ctlShowMessage" runat="server"
Visible="false"
EnableViewState="false"
/>
</div>
要使用,只需调用 ShowMessage ,如 ASPHelper.ShowMessage(“信用不足”)。希望这就是你要找的......基思
答案 6 :(得分:1)
我想建议使用一个类来自定义页面(继承自System.Web.UI.Page),其中添加了以下内容
protected void AlertError(string ErrorString)
{
StringBuilder scriptBuidler =
new StringBuilder(@"<script type='text/javascript' language='javascript'>");
scriptBuidler.Append(@"alert('");
scriptBuidler.Append(ErrorString);
scriptBuidler.Append(@"');");
scriptBuidler.Append(@"</script>");
AjaxControlToolkit.ToolkitScriptManager.RegisterClientScriptBlock
(this, typeof(Page),
"Patient Detail Not Found",
scriptBuidler.ToString(),
false
);
}
并从此类继承您的所有页面,而不是从system.web.ui.page继承 并使用此功能向您的客户显示您的消息
答案 7 :(得分:1)
Javascript安全弹出窗口。适用于Ajax / jQuery。
Namespace Utilities
''' <summary>
''' Utility class for injecting JavaScript into pages. Used primarily for throwing a JavaScript alert box, with correct focus.
''' </summary>
''' <remarks></remarks>
Public Class WriteJava
Public Shared Sub Script(ByVal script As String, ByRef p As Page, Optional ByVal scriptName As String = "")
If String.IsNullOrEmpty(scriptName) Then
scriptName = GetScriptName(p)
End If
If Not p.ClientScript.IsStartupScriptRegistered(scriptName) Then
ToolkitScriptManager.RegisterStartupScript(p, p.GetType, scriptName, script, True)
End If
End Sub
Public Overloads Shared Sub Alert(ByVal MyAlert As String, ByRef p As Page)
Script("alert('" & Format(MyAlert) & "');", p)
End Sub
Private Shared Function Format(ByVal value As String) As String
Return value.Replace("'", "\'").Replace(Chr(13), "\r").Replace(Chr(10), "\n")
End Function
Private Shared Function GetScriptName(ByVal p As Page) As String
Dim i As Integer = p.AppRelativeVirtualPath.LastIndexOf("/")
Dim pageName As String = p.AppRelativeVirtualPath.Substring(i + 1)
Return pageName
End Function
End Class
结束命名空间
通过致电:
使用Utilities.WriteJava.Alert("DANGER WILL ROBINSON", Me.Page)
答案 8 :(得分:1)
在用户控件中引发事件,从页面订阅该事件。事件处理程序更新您的自定义页面属性。似乎运动部件的数量最少。