WebSurfer's Home

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

Chart Samples

by WebSurfer 2016年2月14日 16:15

先の記事 Chart で ASP.NET Web Forms アプリでグラフを表示するのに便利な Chart コントロールを紹介しましたが、MSDN のサイトからサンプルを入手できるので、入手方法その他備忘録として残しておいたほうがよさそうなことを書いておきます。

Chart Samples

まず入手先ですが、以下のページから Windows Forms アプリ用と ASP.NET Web Forms アプリ用のサンプルをダウンロードできます。

Samples Environments for Microsoft Chart Controls

Windows Forms 用のサンプルは上のページで[C# (5.6MB)]をクリック、ASP.NET Web Forms アプリ用なら[HTML (4.4MB)]の方をクリックしてください。両方入手したいなら[Full (10.0MB)]をクリックしてください。

「Samples Environments for Microsoft Chart Controls.zip」という名前の zip ファイルの中に、Windows Forms 用なら「Windows Forms Samples Environment for Microsoft Chart Controls\C#」というフォルダがあって、それに完全な Windows Forms アプリのソリューションとしてサンプルが含まれています。

ASP.NET Web Forms アプリ用なら「ASP.NET Samples Environment for Microsoft Chart Controls\HTML」というフォルダがあって、それに完全な ASP.NET Web Forms アプリの Web サイトプロジェクトとしてサンプルが含まれています。

それを適当なフォルダに解凍して Visual Studio(.NET4 なので 2010 以降のバージョン)で開いて実行すれば、基本の解説、いろいろなタイプのサンプルのデモ、それを作るための C# および VB.NET サンプルコード等が満載のアプリが動くはずです。

上の画像は Windows Forms アプリ用のサンプルを実行したときのものです。ASP.NET Web Forms アプリ用は同様なサンプルがブラウザ上に表示されます。

解説が英語であるのを厭わなければこのサンプルは非常に有益なものになると思います。というか、このサンプル無しでは Chart を使っての開発は難しいと言っても過言でなないと思います。

一つだけ注意事項があります。Windows Forms アプリのサンプルは、ソリューションのフォルダ名が zip を解凍したときのままですと以下の画像のように C# と言う名前になっており、これをそのままソリューションのフォルダとして使う場合は、フォルダ名 C# を CSharp などに書き換えないとうまく動かないということです。(最後が # で終わるのは不可)

フォルダ構成

ちょっと余計な話ですが、何故 '#' があるとダメなのかも調べたので、以下にその理由も書いておきます。

プログラムの中で Application.ExecutablePath プロパティを利用してパス名を得ていますが、.exe ファイルの出力パスが .\ と設定されているので、フォルダ名が C# のままですと得られるパス名の文字列は "C:\ ... \\Windows Forms Samples Environment for Microsoft Chart Controls\\C#/WinFormsChartSamples.exe" となってしまいます。(C# の直後が '\\' ではなくて '/' であることに注意)

その後、上記文字列からファイル名を除去するのに applicationPath.LastIndexOf('\\'); でインデックスを取得しているのですが、'\\' を期待しているところが '/' になっているのでうまく行きません。

C# を CSharp などに書き換えると "C:\ ... \\Windows Forms Samples Environment for Microsoft Chart Controls\\CSharp\\WinFormsChartSamples.exe" となって期待通りに行きます。

何故 C# の直後が '\\' ではなくて '/' なってしまうかと言うと Application.ExecutablePath のコードで '#' が fragment と見なされるからだそうです。

その詳細は以下の記事にありますので興味があれば見てください。(手抜きですみません)

Odd C# path issue

Tags:

.NET Framework

SQL Server Reporting Services と IE11

by WebSurfer 2016年2月10日 14:56

SQL Server Reporting Services (SSRS) のレポートを見るのに IE11 を使うと、表示が崩れるとか印刷ボタンが表示されないなどのトラブルが出るという話を MSDN フォーラムなどで時々聞きます。

その理由を書いた MSDN Blogs の記事を見つけたので忘れないようにその記事へのリンクを張っておきます。

IE 11 browser support for Reporting services versions prior to 2012

その記事によると SQL Server 2012 SP 1 CU 8 より前の Reporting Services は IE11 を検出できないのが原因だそうです。(User Agent が変わったから?)(Edge はまた話が違います。この記事の下の方の 2016/6/9 追記を見てください)

解決策はほとんどなくて、

  1. IE11 の互換表示設定を行う。(これは何の効果もないという話も聞きますが)
  2. バージョン 2012 SP 1 CU 8 以降にアップグレードする。

ぐらいだそうです。

ちなみに、SQL Server 2012 にも同じ問題があって、それは SP1 CU 8 以降のリリースで直したようです。詳しくは以下の Connect の記事を見てください。

SQL Server Reporting Services is not compatible with Internet Explorer 11

上記 Connect では「解決済み」になっていますが、それは SQL Server 2012 SP 1 CU 8 以降のバージョンの話で、それより前のバージョン例えば SQL Server 2008 R2 では直す気はなさそうです。

上記はググって調べただけで、実際に自分の環境で上記の不具合や解決策が有効かを確認したわけではありませんのでご注意ください。

-------- 2016/6/9 追記 --------

MSDN フォーラムの記事「【SSRS】Microsoft Edgeを利用した場合に、印刷ボタンが表示されない」で初めて知ったのですが、Edge は ActiveX をサポートしてないそうです。

なので、SQL Server のバージョンが 2012 SP 1 CU 8 以降でも印刷はできませんのでご注意ください。

Tags: ,

SQL Server

C# と VB.NET のフィールド初期化子の違い

by WebSurfer 2016年2月6日 15:25

C# でフィールドをインスタンスメソッド等で初期化しようとすると「フィールド初期化子は、静的でないフィールド、メソッド、またはプロパティ 'xxx' を参照できません」(xxx はそのメソッド名)というコンパイルエラーになります。

ところが VB.NET ではコンパイラは問題なく通ってしまいます。実行上も、自分が調べた限りですが、期待通り動きました。(ただし、詳しく調べたわけではないので、どんなケースでも問題ないかは分かりませんが)

理由は、想像ですが、C# と VB.NET のコンパイラの違いによるものだと思われます。

(1) Why Do Initializers Run In The Opposite Order As Constructors? Part One、(2) Can VB.NET be forced to initialize instance variables BEFORE invoking the base type constructor?、(3) Field initializer differences between C# and VB.NET 等の記事を読んでみると:

  • C# の場合: まず最初に全ての initializers が derived ⇒ base の順で実行され、次に全ての constructor bodies が base ⇒ derived の順で実行される。
  • VB.NET の場合: constructor bodies が base ⇒ derived の順で実行される。その際、各 initializer は当該 constructor body が実行される直前に実行される。

という違いがあるようです。

知ってました? 実は自分はつい最近まで知らなかったです。(汗) 知っておくべきところは以上なんですが、それだけではブログの記事として面白くないので、無知な自分がハマった話を書いておきます。(笑)

その話は、以下のような VB.NET のコードを C# に書き換えるということから始まりました。

Public Class Sample
    Public Property Code As Integer()

    Public ReadOnly Property Codes As IList(Of Integer)
        Get
            Return Me._Codes.Value
        End Get
    End Property
    
    Private ReadOnly _Codes As New Lazy(Of IList(Of Integer))(
        Function()
            Return If(Me.Code, {}).ToList()
        End Function)
End Class

VB.NET をよく知らない自分は Telerik Code Converter などの変換サービスを利用しています。

自動変換されたコードをそのまま信じて使うのは問題ありと認識していますが、かなりのところまで変換してくれるので多少の手直しで済み、重宝しています。

今回の場合では、VB.NET のコードの If(Me.Code, {}) のところで {} は変換してくれなかったので、そこのみ new int[0] に直して Visual Studio のエディタに貼り付けました。(VB.NET のコードで {} は New Integer() {} と見なされるらしいです。実は、それも知らなかったのですが、さすがに C# で {} ではダメなのは気がつきましたので直しました)

そうすると、以下の画像の赤丸で示した部分でエラーが出ます。

Visual Studio に表示されたエラー

エラーメッセージは最初の方は:「ラムダ式 はデリゲート型ではないため、型 'System.Threading.LazyThreadSafetyMode' に変換できません」(コンパイルした時のエラーメッセージは「ラムダ式 はデリゲート型ではないため、型 'bool' に変換できません。」になります)

2 つ目は:「キーワード 'this' は現在のコンテキストでは使用できません」

となりました。それらのエラーメッセージから原因は分かりますでしょうか? 無知な自分は最初原因が分からず、半日ぐらいハマってしまいました。(汗)

結局原因は、Code がインスタンスプロパティなので(静的ではないので)それを使ってフィールドを初期化することはできないということだったんですが、それなら「フィールド初期化子は、静的でないフィールド、メソッド、またはプロパティ 'Code' を参照できません」というエラーメッセージを出して欲しかったです。(泣き言)

解決策は、変数 _Codes をコンストラクタで初期化するのがよさそうです。(Code プロパティに static キーワードを付与して静的プロパティにするのは止めた方がよさそうです)

Tags:

.NET Framework

About this blog

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

Calendar

<<  2017年1月  >>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar