【问题标题】:Question about events and custom server controls关于事件和自定义服务器控件的问题
【发布时间】:2009-06-06 23:06:19
【问题描述】:

这是我一直困惑的事情。

如果我想制作一个自定义控件,在这种情况下是 Datagrid 控件的子控件,但我想确保当我将鼠标悬停在特定单元格上时,会有一个翻转颜色。如果数据网格没有任何规定(为了论证),我是否必须获取鼠标相对于单元格的坐标,然后突出显示最近的单元格?

谢谢

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    应使用样式表或 JavaScript 定义翻转颜色。这不会通过 ASP.NET 直接控制。您应该让服务器控件生成用于定义悬停样式的 CSS 类,或生成内联 JavaScript。

    使用 CSS 是最好的选择,但是它在 IE6 中不起作用(也许是 IE7,我不记得了)。此示例假定您的控件将数据网格生成为 HTML 表格。由于您的问题是“自定义服务器控件”,因此如果您使用不同的标记呈现控件,这可能会有所不同。确保您的表格具有 MyDataGridClass 的 CSS 类。

    .MyDataGridClass td:hover {
        background: #999;
    }
    

    如果要突出显示整行,可以将上面示例中的 td 更改为 tr

    如果您想在 IE6 中使用悬停样式并且只需要突出显示单个单元格,则可以通过在每个单元格内使用 <a /> 标记来做得更好。 IE6 错误地实现了悬停伪选择器,因此它仅适用于 <a /> 标记,这就是为什么它会起作用,但上述内容在 IE6 中不起作用:

    .MyDataGridClass a {
        display: block;
        width: 100%;
        height: 100%;
        padding: 0px;
        margin: 0px;
    }
    
    .MyDataGridClass a:hover {
        background: #999;
    }
    

    当然,此示例假定您能够将 CSS 嵌入到您将放置控件的页面中。如果由于某种原因你没有这个选项,你可以走 JavaScript 路线,但这不是做事的首选方式。如果您有兴趣了解如何使用 JavaScript 进行此操作,请告诉我。

    更新:
    下面的部分解决了您留下的第一条评论。我保留了原件,以防有人发现它有用。


    为了创建事件驱动控件,您应该实现IPostBackEventHandlerIPostBackDataHandler。如果需要了解这2个接口的区别,可以see this question。我宁愿不在这里包含详细信息,因为它会使这个答案太长。

    此示例使用IPostBackEventHandler,但IPostBackDataHandler 非常相似。

    您需要做一些事情来处理 PostBack 事件:

    • 创建一个密钥以用作您的事件的标识符。这用于base.Event 键/值集合。在此示例中,我使用的是 _EventClick 对象。
    • 使用base.Events[] 设置/注册您的活动,以便在回发期间维护活动订阅者。
    • 渲染控件时,调用Page.ClientScript.GetPostBackEventReference。这将生成对 ASP.NET 的 __doPostBack JavaScript 方法的函数调用。您可以在您呈现的任何 JavaScript 事件属性中使用此脚本。

    这是对 ASP.NET LinkBut​​ton 控件的最小重新创建。大多数“魔法”发生在AddAttributesToRender()RaisePostBackEvent() 方法中。

    public class ControlWithEvent : WebControl, IPostBackEventHandler
    {
        private object _EventClick = new object();
    
        protected override HtmlTextWriterTag TagKey
        {
            get { return HtmlTextWriterTag.A; }
        }
    
        public event EventHandler Click
        {
            add
            {
                base.Events.AddHandler(_EventClick, value);
            }
            remove
            {
                base.Events.RemoveHandler(_EventClick, value);
            }
        }
    
        public void RaisePostBackEvent(string eventArgument)
        {
            // The value of the 'eventArgument' parameter will be "myOptions" 
            EventHandler handler = (EventHandler)base.Events[_EventClick];
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }
    
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);
    
            // "myOptions" can be anything, including an empty string.
            // You can use it for your EventArgs object if you need it.
            PostBackOptions options = new PostBackOptions(this, "myOptions");
    
            string script = Page.ClientScript.GetPostBackEventReference(options, false);
    
            writer.AddAttribute(HtmlTextWriterAttribute.Onclick, script);
        }
    
        public string Text { get; set; }
    
        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write(Text);
        }
    }
    

    如果你想在你的控件中包含额外的 JavaScript 逻辑,我建议你阅读 this article 在 ASP.NET 中包含 JavaScript 以了解如何在 ASP.NET 中注册脚本。

    【讨论】:

    • 谢谢。我不需要你展示其他任何东西。我知道如何使用 js 突出显示特定的行/单元格。我问这个问题是因为我需要了解自定义控件和事件(如果您知道任何好的链接,请随时列出它们):)。
    • @dotnetdev 我已根据您的评论更改了答案以与您所说的要查找的内容保持一致。希望这更多是您想要的。
    • 其实,这两个答案都非常有用。回顾一下,突出显示数据网格中的行或单元格的最简单方法是通过具有所需样式的纯 css(通过皮肤等确保 css 是控件的一部分)。这基本上是您提供的第一种方法,对吧?
    • 对。如果可能,您应该始终使用 CSS 应用样式(例如悬停样式)。它保持了内容、逻辑和风格的良好分离,这是您应该始终努力的目标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 2013-11-09
    相关资源
    最近更新 更多