C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2011/05/20 00:42
DDD サンプルを公開しましたので解説記事とか書きたいのですが、その前に、同じアプリケーションアーキテクチャでアプリを開発するためのテンプレートか何かをこしらえようと思ってます。
ただ、プロジェクトのテンプレートは作成できてもソリューションのテンプレートは作成できないっぽいので、別の形を考えています。(複数プロジェクトを一つのテンプレートにすることはできるみたいですが、ソリューションフォルダの自由度が低いので。)

タグ:
2009/05/06 02:19
セットアッププロジェクトのカスタム動作でメッセージボックスを普通に使おうとしても、インストーラのウィンドウとの親子関係を持たせることができません。そのため、インストーラのウィンドウの方が前面に表示されてしまったりする場合があります。

インストーラのウィンドウのハンドルさえ取得できれば、NativeWindow クラスを使って親子関係を持たせることもできるのですが、生憎取得できないようです。Process.MainWindowHandle で取得できるかとも思いましたが 0 が返ってきました。

そこで、ちょっと知恵を絞り出してみました。

internal static class MyMessageBox
{
    public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
    {
        using (Form dummy = MyMessageBox.ShowDummyForm(caption))
        {
            return MessageBox.Show(dummy, text, caption, buttons, icon, defaultButton);
        }
    }

    private static Form ShowDummyForm(string caption)
    {
        Form dummy = new Form();
        dummy.TopMost = true;
        dummy.ShowInTaskbar = true;
        dummy.Opacity = 0;
        dummy.ControlBox = false;
        dummy.Text = caption;
        dummy.Show();
        return dummy;
    }
}

最前面に固定された透明のダミーウィンドウを表示し、それをメッセージボックスの親ウィンドウにしたわけです。
この方法だとメッセージボックスがタスクバーに表示されませんが、ControlBox プロパティと Text プロパティを変更することで、ダミーウィンドウがちょうど良い具合に代わりを果してくれます。

メッセージボックスが最前面に固定されてしまうという副作用はありますが、まぁ問題ないでしょう。
あと、インストーラのウィンドウとダミーウィンドウ及びメッセージボックスはあくまで無関係ですので、メッセージボックス表示中もインストールウィンドウの操作が従来通りできてしまうことには注意してください。
2009/03/24 13:11
以前は、Sandcastle Help File Builder のプロジェクトをコマンドラインからビルドするためのツールとして "SandcastleBuilderConsole.exe" が同梱されていましたが、現在のバージョンには含まれていません。

コマンドラインからビルドするにはどうすれば良いのか調べてみたところ、MSBuild を使ってビルドするようになっていました。
確かに、プロジェクトファイルのフォーマットが MSBuild のフォーマットになっていますし、拡張子も変わっています。

使用するビルド設定に "Release" を指定して "C:\Projects\Sample\Sample.shfbproj" にあるプロジェクトファイルをビルドするには次のコマンドを実行します。

%SystemRoot%\Microsoft.NET\Framework\v3.5\MSBuild.exe /p:Configuration=Release "C:\Projects\Sample\Sample.shfbproj"


MSBuild を使ったビルド方法の詳細は、Sandcastle Help File Builder HelpBuilding Projects Outside the GUI に記載されています。
タグ: .NET C# Sandcastle
2009/02/23 10:44
仙台で勉強会が開催されるそうです。(僕は参加できません…。)
イベント名は「コミュニティ勉強会に参加しよう」です。
仙台近辺の方々、是非ご検討頂ければと思います。
(コミュニティ勉強会に参加したことのない僕が宣伝するのもアレですが、ソレはソレということで是非^^;)
INETA & techbank.jp & PowerShell from Japan!! & HIRO's.NET 合同勉強会 in 仙台
タグ: 勉強会
2008/09/28 02:50

static class Program
{
    static void Main()
    {
        Hoge h = null;
        h.Safely().Fuga();
    }
}

public class Hoge
{
    static public readonly Hoge Null = new NullHoge();

    public virtual void Fuga()
    {
    }

    private class NullHoge : Hoge
    {
    }
}

static public class HogeExtension
{
    static public Hoge Safely(this Hoge source)
    {
        return (source != null) ? source : Hoge.Null;
    }
}


Imports System.Runtime.CompilerServices

Module Module1
    Sub Main()
        Dim h As Hoge = Nothing
        h.Safely()
        h.Fuga()
    End Sub
End Module

Public Class Hoge
    Public Shared ReadOnly Null As Hoge = New NullHoge()

    Public Sub Fuga()
    End Sub

    Private Class NullHoge
        Inherits Hoge
    End Class
End Class

Public Module HogeExtension
    <Extension()> _
    Public Sub Safely(ByRef source As Hoge)
        If (source Is Nothing) Then
            source = Hoge.Null
        End If
    End Sub
End Module
タグ: .NET C# VB
2008/09/10 02:01
いいもの見っけた (`・ω・´)

Mokosh | VsCommands

ソリューションエクスプローラで、ファイルを複数選択して右クリック → [Group Items] をクリックすると選択したファイルがグループ化される。多段の入れ子にすることもできる。
ファイルの複数選択は Ctrl キー押しながらファイルをクリックしてけばオッケー。

ちなみに、ファイルを入れ子にするって指定は元々プロジェクトファイルがサポートしている機能 (DependentUpon 要素) なので、VSCommands をインストールしていない Visual Studio で開いてもちゃんと入れ子になって表示される。


よし、これでさっきここに書いた

├─ Hoge.cs
├─ Hoge.Test.cs
├─ HogeFactory.cs
└─ HogeFactory.Test.cs

ってのが

□─ Hoge.cs
 └─ Hoge.Test.cs
□─ HogeFactory.cs
 └─ HogeFactory.Test.cs

って具合に入れ子にできる (^ω^)


追記 (2008/10/17)
バージョン 1.2 がリリースされています。
嬉しい事に、Ctrl キーを押しながら Group Items をクリックすることで、ルートにしたいファイルを選択可能になっています。
また、ファイルを入れ子にする機能以外の機能がいくつか備わったようです。

それと、リンク先の URL が変更になったようなので貼り直しました。
タグ:
2008/01/31 00:26
今まで LINQ to Object の基本くらいしか知らなかったので、今日は大収穫を得た。
一番の収穫はやはり LINQ to SQL。
つか、LINQ to SQL の場合、where 句のラムダ式が SQL の where 句に変換されるというのは、正直半信半疑だった。
で、帰宅して早速試してみた。

static void Main(string[] args)
{
    DataContext context = new DataContext(Settings.Default.Database1ConnectionString);
    var query =
        from target in context.GetTable<Table1>()
        where (target.Column1 == "a")
        select target;

    string queryText = query.ToString();
    Console.WriteLine(queryText);
}

[Table(Name = "Table1")]
class Table1
{
    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int PrimaryKey;

    [Column]
    public string Column1;
}

実行結果
SELECT [t0].[PrimaryKey], [t0].[Column1]
FROM [Table1] AS [t0]
WHERE [t0].[Column1] = @p0


Σ(゚д゚lll)ガーン

ホントに where 句が where 句に・・・!
そういや、LINQ to SQL のラムダ式はデリゲートではなく System.Linq.Expressions.Expression オブジェクトに変換されると言っていたな。
逆コンパイルしてみると、確かに・・・つーか結構複雑なことやってるな。target.Column1 == "a" というラムダ式から、target とか Column1 とか == 演算子なんかのメタデータを採取して、それを元に Expression オブジェクトを構築するようなコードへと変換されている。
なるほどなるほど。

でもまぁこんなクエリー式はさすがに無理だろ。

var query =
    from target in context.GetTable<Table1>()
    where (target.Column1[1].ToString() == "a")
    where (target.Column1.IndexOf("b") <= 3)
    select target;

実行結果
SELECT [t0].[PrimaryKey], [t0].[Column1]
FROM [Table1] AS [t0]
WHERE ((
    (CASE
        WHEN (DATALENGTH(@p0) / 2) = 0 THEN CONVERT(BigInt,0)
        ELSE CONVERT(BigInt,(CONVERT(Int,CHARINDEX(@p0, [t0].[Column1]))) - 1)
     END)) <= @p1) AND ((CONVERT(NVarChar(MAX),CONVERT(NChar(1),SUBSTRING([t0].[Column1], @p2 + 1, 1)))) = @p3)




( ゚Д゚ ) ・・・。



タグ: .NET C# ADO.NET LINQ
2007/09/26 20:05
どうでもいいっちゃどうでもいいことですが、下の2つのページを見比べると、URL の最後の方に "(VS.80)" が付いていない方のページでは、「重要」という項目が表示されています。この「重要」の中で、.NET Framework 2.0 以降ではこのインターフェイスの代わりに ConfigurationSection クラスから派生するように、と書かれています。"(VS.80)" が付いている方のページではこのことが書かれていません。

"(VS.80)" 有り
IConfigurationSectionHandler インターフェイス (System.Configuration)

"(VS.80)" 無し
IConfigurationSectionHandler インターフェイス (System.Configuration)


で、今度は ConfigurationSection クラスだと、"(VS.80)" が付いている方には「メモ : このクラスは、.NET Framework version 2.0 で新しく追加されたものです。」と書かれているのに "(VS.80)" が付いていない方には書かれていません。

"(VS.80)" 有り
ConfigurationSection クラス (System.Configuration)

"(VS.80)" 無し
ConfigurationSection クラス (System.Configuration)


しかも、よくよく眺めてみると、他にもちらほら違いがあります。
で、更によくよく見ると、"(VS.80)" が付いているページと付いていないページとでは、ページ階層も異なるようで、"(VS.80)" が付いているページは「以前のバージョン」というページの下の方にぶらさがっているようです。


まぁ、だからどうしたと言う訳でもなく、ただそれだけです。
ページによっては、URL から "(VS.80)" を除いたとしても勝手に補完される場合もあるようです。
タグ: .NET MSDN
2007/09/17 21:28
けっこうややこしいのでメモ。

// using System;
// using System.Drawing;
// using System.Drawing.Imaging;
// using System.IO;

static void Main()
{
    Image page1 = new Bitmap("C:\\work\\page3.bmp");
    Image page2 = new Bitmap("C:\\work\\page3.bmp");
    Image page3 = new Bitmap("C:\\work\\page3.bmp");

    // TIFF 形式のエンコーダ。
    ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders();
    Predicate<ImageCodecInfo> tiffEncoderPredicate =
        delegate(ImageCodecInfo input)
        {
            return (input.FormatID == ImageFormat.Tiff.Guid);
        };
    ImageCodecInfo tiffEncoder = Array.Find(imageEncoders, tiffEncoderPredicate);

    // エンコーダのパラメータ。
    EncoderParameters tiffEncoderParameters = new EncoderParameters(2);
    tiffEncoderParameters.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
    tiffEncoderParameters.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone);

    // 作業領域となるメモリストリーム。
    MemoryStream tiffStream = new MemoryStream();
    // Save メソッドによって、1ページ目が保存され、更に Image オブジェクトとメモリストリームが関連付けられる。
    page1.Save(tiffStream, tiffEncoder, tiffEncoderParameters);

    // 2ページ目, 3ページ目の保存に使用するエンコーダのパラメータ。
    EncoderParameters pageEncoderParameters = new EncoderParameters(2);
    pageEncoderParameters.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
    pageEncoderParameters.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone);

    // 先ほどの Save メソッドで関連付けられたメモリストリームに対して保存される。
    // この操作は page1 にフレームを追加するわけではない。
    page1.SaveAdd(page2, pageEncoderParameters);
    page1.SaveAdd(page3, pageEncoderParameters);

    // メモリストリームの内容をファイルに保存する。
    File.WriteAllBytes("C:\\work\\test.tif", tiffStream.ToArray());
}



EncoderParameter のインスタンスを生成する際、EncoderValue 列挙値を long にキャストして渡しています。これは int ではなく long にしなければいけません。でないと失敗します。

サンプルなんで Dispose メソッドは呼び出してません。Image, MemoryStream  以外にも、EncoderParameters や EncoderParameter も IDisposable を実装してます。
タグ: .NET C# 画像処理
2007/06/30 16:18
オンラインの MSDN ライブラリの方も、.NET Framework 3.0 関連のページが日本語化されてますね。
このブログの WCF の記事、全部日本語ページへのリンクに張り替えないと。。。
タグ: