Question

kenji nishiya on Wed, 19 Jun 2013 03:05:10


お世話になります。
埋め込みリソースを使ったカスタムコントロールの継承で悩んでいます。

・環境
VisualStudio2012 pro
.net Freamwork 4.5
C#
ASP.NET
で開発しています。

・プロジェクト構成
Commonプロジェクト

|--Ctrl
|      |--jQuery
|      |         |--datepicker.css(埋め込まれたリソース)
|      |         |--datepicker.js(埋め込まれたリソース)
|      |
|      |
|      |--ExDatepicker.cs(assembly: WebResourceを使って上のjQuery配下にあるcssとjsを指定)
|      |--ExTextBox.cs
|      |--ExDropDown.cs
|      |--ExListBox.cs




WebSiteプロジェクト(Commonプロジェクト参照に追加)

|--Ctrl
|      |--ExDatepicker.cs(上のCommonにあるExDatepickerを継承)<=継承だと現在使えない
|      |
|      |--ExTextBox.cs(上のCommonにあるExTextBox.csを継承)
|      |--ExDropDown.cs(上のCommonにあるExDropDown.csを継承)
|      |--ExListBox.cs(上のCommonにあるExListBox.csを継承)



普段はページにRegisterを使って(WebSite.Ctrlを)指定し、カスタムコントロールを使うようにしています。
<%@ Register Assembly="WebSite.Ctrl" Namespace="WebSite.Ctrl" TagPrefix="cc1" %>

今回初めて埋め込みリソースを使ってCommonプロジェクト側のExDatepickerクラスを以下のように(多少割愛してますが)作りました。
<%@ Register Assembly="Common.Ctrl" Namespace="Common.Ctrl" TagPrefix="cc2" %>
と書いて動くことは確認しています。

が普段はWebSite.Ctrlの場所のカスタムコントロールを使うように統一しています。
(他のコントロールは埋め込みリソースは使っていません。また、継承した形でも使えています。)

ので、どうしても埋め込みリソースを使ったカスタムコントロールを継承した形で扱いたいのです。
ご存知の方いらっしゃいましたら、教えて頂きたいと思って質問させていただきました。


WebSite.Ctrl側のExDatepickerクラス

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using AjaxControlToolkit;

[assembly: WebResource("Common.Ctrl.Datepicker.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("Common.Ctrl.Datepicker.js", "text/javascript", PerformSubstitution = true)

namespace Common.Ctrl
{
    [DefaultProperty("Text"),
    ToolboxData("<{0}:ExDatepickerTextBox runat=server></{0}:ExDatepickerTextBox>")]
    public class ExDatepicker : TextBox
    {
        protected override void CreateChildControls()
        {
            ClientScriptManager cs = Page.ClientScript;
            Type rsType = this.GetType();

            HtmlLink css = new HtmlLink();
            css.Href = cs.GetWebResourceUrl(rsType, "Common.Ctrl.Datepicker.css");
            css.Attributes["rel"] = "stylesheet";
            css.Attributes["type"] = "text/css";
            css.Attributes["charset"] = "utf-8";
            css.Attributes["media"] = "all";
            // スタイルシート追加
            Page.Header.Controls.Add(css);
            //ベーススクリプト追加
            cs.RegisterClientScriptInclude(rsType, "ExDatepicker", cs.GetWebResourceUrl(rsType, "Common.Ctrl.Datepicker.js"));

            // jQuery スクリプト記述
            StringBuilder script = new StringBuilder(string.Empty);
            script.AppendLine("");
            script.AppendLine("Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded( function (evt, args) { ");
            script.AppendLine(@"     $('#" + this.ClientID.ToString() + "').DatePicker({");

            ///
            ///  中身記述
            ///

            script.AppendLine("     });");
            script.AppendLine(" });");
            cs.RegisterStartupScript(rsType, this.ID, script.ToString(), true);

            base.CreateChildControls();

        }
    }
}


WebSite.Ctrl側のExDatepickerクラス

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Web.UI;

namespace WebSite.Ctrl
{
    [DefaultProperty("Text"),
    ToolboxData("<{0}:ExDatepicker runat=server></{0}:ExDatepicker>")]
    public class ExDatepicker : Common.Ctrl.ExDatepicker
    {
    }
}

Sponsored



Replies

SurferOnWww on Wed, 19 Jun 2013 05:28:27


> 埋め込みリソースを使ったカスタムコントロールの継承で悩んでいます。

リソース埋め込みカスタムコントロールが継承できないと言われていますか? 具体的に、何をどうすると、どのような結果になることを期待していて、実際に試すとどのように期待と異なる結果になるのでしょう?

kenji nishiya on Wed, 19 Jun 2013 06:20:45


お世話になっております。

リソース埋め込みカスタムコントロールを継承しても動かないのです。

前提としまして、CommonのExDatepickerではベースはテキストボックスです。

datepicker.css(埋め込まれたリソース)
datepicker.js(埋め込まれたリソース)

このExDatepickerでは、このふたつのCssとJsファイルを読み込みにフォーカスがあたった時にカレンダーが表示されるものです。

<%@ Register Assembly="Common.Ctrl" Namespace="Common.Ctrl" TagPrefix="cc2" %>

で記述し、使うとこのExDatepickerはきちんとカレンダー表示されます。

cssとjsファイルがページに埋め込まれています。

問題になっているのは、ここからです。

ただ、参照方法は

<%@ Register Assembly="WebSite.Ctrl" Namespace="WebSite.Ctrl" TagPrefix="cc1" %>

これに統一しています。

のでCommon側のExDatepickerを継承する形でWebSite.Ctrl配下にクラスを作りました。

この継承した状態でのExDatepickerでは、カレンダーが表示されず、ただのテキストボックスの状態となっています。

cssとjsファイルがページに埋め込まれていません。

これでわかりますでしょうか?


SurferOnWww on Thu, 20 Jun 2013 01:44:46


アップされたコードを拝見すると、ClientScriptManager.GetWebResourceUrl メソッドの引数の一つ Type に this.GetType() を渡していますが、そうすると継承先のコントロール (this) のアセンブリからリソースを探すので、結果、リソースが見つからないということになっているのだと思います。

Type rsType = this.GetType();

Type rsType = typeof(ExDatepicker);

に変更して試したらどうなりますか?

kenji nishiya on Thu, 20 Jun 2013 04:03:40


お世話になっております。

今しがた試した結果。

無事にうまく動きました。ありがとうございます。