WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

リソースから画像を取得する際の注意点

by WebSurfer 2018年2月6日 17:02

リソースから画像を取得すると、取得するたび毎回新しい Bitmap オブジェクトが生成されるいう話を書きます。(元の話は MSDN Forum のスレッド「C#でのIF文を使ったフォーム背景画像の設定方法について」のものです)

リソースの画像

Visual Studio 2015 のテンプレートから Windows Forms アプリを生成すると、Properties フォルダ下にリソースファイル Resources.resx と厳密に型指定されたリソースクラス Resources.Designer.cs が自動生成されます。上の画像は、そのリソースに .png ファイルを追加したものです。

そうすると、厳密に型指定されたリソースクラス Resources.Designer.cs に以下のコードが自動生成されて、image プロパティでリソースの .png ファイルから Bitmap オブジェクトを取得できるようになります。

internal static System.Drawing.Bitmap image {
  get {
    object obj = 
      ResourceManager.GetObject("image", resourceCulture);
    return ((System.Drawing.Bitmap)(obj));
  }
}

image プロパティは ResourceManager.GetObject メソッドを使っているところに注目してください。

MSDN ライブラリ ResourceManager.GetObject メソッド (String, CultureInfo) の説明によると "同じ name パラメーターで GetObject メソッドを複数回呼び出した場合、戻り値が同じオブジェクトの参照になるとは限りません・・・" とありますが、画像の場合は毎回新しい Bitmap オブジェクトが生成されるようです。

リソースから画像取得

上の画像で isEqual1 が false になることがそれを裏付けていると思います。isEqual2 は当然ながら true になります。

それがどうしたって言われそうですが、自分としては新しい発見だったということで備忘録として書いておくことにしました。(笑)

Tags: ,

.NET Framework

inc ファイルの C# コードにブレークポイント

by WebSurfer 2018年1月22日 19:02
ASP.NET で使用する .inc ファイルの C# コードにブレークポイントを設定するにはどうすればいいかを書きます。(そもそも .inc ファイルに C# のコードを書く必要があるのかという話はちょっと置いときます)

inc ファイルのコードにブレークポイント

元の話は terateil のスレッド ASP.NETのデバッグについてです。

C# のコードを .inc ファイルに含めて、コードビハインドの .aspx.cs ファイルの C# のコードと同様に ASP.NET にコンパイルさせることができます。

ただし、少なくとも自分の環境では、デフォルトではブレークポイントを設定できませんでした。クリックして特定の行にブレークポイントを設定しようとすると <script runat="server"> の行に設定されるように見えますが、デバッグ実行で止まりません。

どうすればよいかと言うと、Visual Studio の設定で[ツール(T)]⇒[オプション(O)...]⇒[テキストエディタ]のファイル拡張子に inc を追加してやります。

テキストエディター、ファイル拡張子の設定

Visual Studio のヘルプによると、この設定で "特定の拡張子を持つすべてのファイルを Visual Studio 統合開発環境 (IDE) で扱うように指定できます" とのことです。文字のハイライトやインテリセンスが働くようになるだけでなく、ブレークポイントの設定も可能になります。(自分の環境では、.inc ファイルをいったん閉じて再度開く必要がありましたが)

知ってました? 実は、自分は teratail のスレッドで聞くまで知らなかったです。もっと正直に言うと、C# のコードを .inc ファイルに含めても、リテラル扱いとなって、生の C# のコードがそのまま html ソースに出力されると思ってました。(汗)

以下に、検証に使ったコードと、若干のコメント・注意点を書いておきます。

.inc ファイル

この例では JavaScript のコードと C# のコードの両方を含めました。JavaScript のコードは、インラインで .aspx ファイルに書き込んだのと同様にリテラルとして取り込まれ、そのまま html ソースに書き出される。一方、C# のコードはコードビハインド扱いとなり、.aspx.cs ファイル の C# のコードと同様にコンパイルされます。

System.Diagnostics.Debugger.Break(); はブレークポイントが設定できないと思ったので代わりに置いたものです。不要となったのでコメントアウトしました。

<script type="text/javascript">
    var msg = "message";
    // alert(msg);
</script>

<script runat="server">
    protected void Selection_Change(Object sender, EventArgs e)
    {
        //System.Diagnostics.Debugger.Break();
        
        DropDownList ddl = (DropDownList)sender;

        Label1.Text = ddl.SelectedValue;
        
        int i;
        for (i = 0; i < 10; i++)
        {
            //System.Diagnostics.Debugger.Break();
        }
        
        Label1.Text += ", i = " + i.ToString();
    }
</script>

.aspx.cs ファイル

コードビハインドとして Visual Studio が自動生成した C# のコードです。自動生成されたコードのそのままで手は加えていません。

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

public partial class _0023_includeFile : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        
    }
}

.aspx ファイル

<!-- #include file ="analytics.inc" --> で上の .inc ファイルを取り込みます。本体には DropDownList と Label を配置。DropDownList の SelectedIndexChanged イベントのハンドラは .inc ファイルの C# のコードに定義しました。

ASP.NET がこのコードをコンパイルする際、.inc ファイルの JavaScript のコードはそのままリテラルとして取り込まれます(結果、html ソースにはその位置にそのまま JavaScript のコードが書き出されます)。.inc ファイルと .aspx.cs ファイルの C# のコードはコンパイルされます。

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeFile="0023-includeFile.aspx.cs" 
    Inherits="_0023_includeFile" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
  <!-- #include file ="analytics.inc" -->
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:DropDownList id="ColorList"
      AutoPostBack="True"
      OnSelectedIndexChanged="Selection_Change"
      runat="server">
      <asp:ListItem Selected="True" Value="White">
        White
      </asp:ListItem>
      <asp:ListItem Value="Silver">
        Silver
      </asp:ListItem>
      <asp:ListItem Value="DarkGray">
        Dark Gray
      </asp:ListItem>
      <asp:ListItem Value="Khaki">
        Khaki
      </asp:ListItem>
      <asp:ListItem Value="DarkKhaki">
        Dark Khaki
      </asp:ListItem>
    </asp:DropDownList>
    <br />
    <asp:Label ID="Label1" runat="server" />
  </div>
  </form>
</body>
</html>

Tags: ,

ASP.NET

Ajax Control Toolkit デモ

by WebSurfer 2017年12月16日 20:25

Ajax Control Toolkit の最新版(この記事を書いた時点では v17.1.1.0)のデモを自分の開発環境で動くようにする手順を備忘録として書いておきます。

Ajax Control Toolkit デモ

DevExpress のサイト ASP.NET AJAX Control Toolkit Demos にデモは公開されていますが、自分の開発環境に同じものをインストールし、ソースコードを見たりデバッグ実行したいということがあると思います。

そのためには、まず、GitHub のサイト DevExpress/AjaxControlToolkit から AjaxControlToolkit-master.zip をダウンロードします。

ダウンロードしたファイル AjaxControlToolkit-master.zip の中に AjaxControlToolkit.SampleSite というフォルダがあるので、それを丸ごと解凍して適当な場所にコピーします。

v7.x までは、それを Visual Studio で開いて[デバッグ(D)]⇒[デバッグなしで開始(H)]で実行すれば動いたのですが、v17.1.1.0 では AjaxControlToolkit が見つからないというエラーになります。

基本的には NuGet で必要なパッケージをインストールして web.config を一部修正すれば動くようになるのですが、かなり多くのパッケージをインストールしなければならず、エラーメッセージも意味不明なものがあり、動くようになるまで 2 日ほどハマってしまいました。(笑)

NuGet

自分が NuGet からインストールしたパッケージおよびそのバージョンは以下の通りです。

  1. AjaxControlToolkit v17.1.1
  2. Microsoft.AspNet.Web.Optimization v1.1.3
  3. Microsoft.AspNet.Web.Optimization.WebForms v1.1.3
  4. AjaxControlToolkit.StaticResources v17.1.1
  5. WebGrease v1.6.0
  6. AjaxControlToolkit.HtmlEditor.Sanitizer v17.1.1
  7. HtmlAgilityPack v1.6.7
  8. Antlr v3.5.0.2
  9. Newtonsoft.Json v10.0.3
  10. Microsoft.Web.Infrastructure v1.0.0

web.config の修正箇所は以下の通りです。

  1. <trust level="Medium" /> を削除(理由不明ですが Visual Studio 2015 で IIS Express 64-bt で動かした場合はこれがあるとダメ)
  2. siteMap / providers 要素に <remove name="MySqlSiteMapProvider" /> を追加(これは MySQL の Connector/NET をインストールした自分の環境固有の問題)

上に書いた NuGet でのパッケージのインストールが完了するとアプリケーションの bin フォルダは以下のようになるはずです。

bin フォルダ

以下に自分的に注意すべきと思う点を書いておきます。

WebGrease, HtmlAgilityPack など[ソリューションの NuGet パッケージの管理]ではインストール済みと表示されるものがあります。その場合、新しいバージョンがリリースされていたら更新することでインストールできます。

Microsoft.Web.Infrastructure は新しいバージョンがない(1.0.0 しかない)ので[ソリューションの NuGet パッケージの管理]ではインストールできません。その場合は[パッケージマネージャーコンソール(O)]で以下のようにしてインストールできます。

Update-Package -reinstall Microsoft.Web.Infrastructure

HtmlEditorEntender には AjaxControlToolkit.HtmlEditor.Sanitizer が必要です。これなしで起動しようとすると以下のように "値を Null にすることはできません。パラメータ名:Type" という意味不明なエラーになります。これの原因が分からなくてハマりました。(汗)

エラーメッセージ

加えて、HtmlAgilityPack も必要です。もういい加減にカンベンしてって感じだったのですが、一応ここまででとりあえず動くようにはなりました。(笑)

Tags: ,

AJAX

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  2018年9月  >>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

View posts in large calendar