2008年10月8日水曜日

[他]インテリセンスが英語に?

先日、C#.NET 2008 Express Edition SP1に入れ替えました。
簡単なサンプルを作っていると違和感が。。。そうなんです。インテリセンスの説明が英語になっているではないですか。なんだそりゃ。

ディベロッパー製品開発統括部 Blogによると、「また、Visual Studio の開発環境中に表示される Intellisense ですが、現在一部英語で表示される箇所があります」だそうです。っていうかほとんど英語のように感じました。

また、同じマシンにインストールしてあるC#.NET 2005 Express Editionを何気に開いてみると、なんとこっちのインテリセンスも英語になっちゃってます。2008に巻きこまれたようです。いつ直ることやら。。。

2008年10月7日火曜日

[他]ソケットのエラー コード

Socketで発生するエラーコードについてまとめられているURLが紹介されていました。備忘録としてメモ。
Windows ソケットのエラー コード、値、および意味

2008年10月5日日曜日

[他]定義に移動(G)(VS2005,2008)

先日@itの掲示板を見ていると、「ctrl + shift + F2 で戻れない」という話題がありました。

コレは、コンテキストメニューの「定義に移動(G)」など、ジャンプ系の機能を実行した後、呼び出し元に戻るという昨日をショートカットで呼び出すというものなのですが、私この「定義に移動(G)」を結構使います。そのため「ウホ、ソレ便利かも」と思って実際にやってみました。が、動作しませんでした。

で、キーボードの反応が悪かったのか?と思い、偶然F2を押してみると、なんと「リファクタリング」の「名前の変更(G)」が動くではないですか!!コレは、エクスプローラやExcelの選択したオブジェクトの名前(データ)変更と同じのなで、一発で記憶することができました。

私、結構メソッド名変更するタイプなので、いいショートカットを覚えられました。

該当のスレッドを追っていくとヒントがありますが、「ctrl + shift + F2 」はVB系のキーバインドらしく、VS標準はCTRL+[-]ということでした。ちなみに「定義に移動(G)」はF12です。この組み合わせも結構便利かも。

2008年10月1日水曜日

[他]SQLで最小値の一覧を取得する

先日@itを見ていると、「キー値が同一のとき、キー以外の値が最小のデータを効率よく取得するには」という話題が挙がりました。

で、私が思いつく方法といえば、サブクエリで最小値の一覧を取得しその値の一覧を連結するという方法です。コードはこんなかんじ(手打ち未検証)。

SELECT 
     key
    ,code
    ,value1
    ,value2 
FROM table1
WHERE
(key,code) IN (SELECT key ,MIN(code) FROM table1 GROUP BY key,code)


このほかにINNER JOINする方法を思いつきました。
しかし、このスレッドでは私が思いついた方法以外の方法が紹介されていました。おそらく私の思いついた方法はコストが高いと思います。集計関数を使わずにできるとは。。。いやー勉強になりますねぇ。

2008年9月30日火曜日

[.NET]普通のボタンにショートカットキーを割り当てる(その2)

先日ダミーのメニューを使ったボタンのショートカット機能ですが、別の方法として、ErrorProviderっぽい実装ができないか考えてみました。実装してみるとそれらしく動作しました。

コンポーネントなので、デザイナーのFormにドロップすればよいのですが、TargetForm(ComponetからFormを取得す方法がわからない)とKeyPreviewプロパティをそれらしく設定する必要があります。
FormのKeyPreviewの代わりに、このコンポーネントのKeyPreviewをTrueにすると、初期化時にTargetFormのTargetFormをそれらしく設定します。

/// <summary>
/// ショートカットキー機能を付加するExtenderProvide
/// </summary>
[ProvideProperty("ShortcutKeys", typeof(Control))]
public partial class ShortcutKeyProvider : Component, IExtenderProvider, ISupportInitialize
{
    /// <summary>
    /// 情報格納エリア
    /// </summary>
    private Dictionary<Keys, Control> extInfo = new Dictionary<Keys, Control>();
    
    private Form targetForm = null;
    /// <summary>
    /// 対象のForm
    /// </summary>
    [Description("ショートカットを有効にする対象のform")]
    public Form TargetForm
    {
        get { return targetForm; }
        set { targetForm = value; }
    }

    private bool keyPreview = true;
    /// <summary>
    /// キーイベントの設定
    /// </summary>
    /// <remarks>FormのKeyPreviewがFalseの場合、この値をFormのKeyPreviewに設定します</remarks>
    [Description("キーボードイベントがフォームとともに登録されるかを決定します")]
    public bool KeyPreview
    {
        get { return keyPreview; }
        set { keyPreview = value; }
    }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public ShortcutKeyProvider()
    {
        InitializeComponent();
    }

    /// <summary>
    /// コンテナ指定付コンストラクタ
    /// </summary>
    /// <param name="container">コンテナ</param>
    public ShortcutKeyProvider(IContainer container)
    {
        container.Add(this);

        InitializeComponent();
    }

    #region ISupportInitialize メンバ

    /// <summary>
    /// 初期化の開始
    /// </summary>
    public void BeginInit()
    {
    }

    /// <summary>
    /// 初期化の終了
    /// </summary>
    public void EndInit()
    {
        //キー押下イベントを設定
        if (TargetForm != null)
        {
            TargetForm.KeyDown += new KeyEventHandler(TargetForm_KeyDown);
            if (TargetForm.KeyPreview == false)
            {
                System.Diagnostics.Debug.WriteLine("****FORMのKeyPreviewを変更します!! ==> " + KeyPreview);
                TargetForm.KeyPreview = KeyPreview;
            }
        }
    }

    #endregion



    #region IExtenderProvider メンバ

    bool IExtenderProvider.CanExtend(object extendee)
    {
        //ボタンのみ対応する.対応するコントロールを増やすならここに追加
        return extendee is Button;
    }

    #endregion

    /// <summary>
    /// ショートカットキーの取得
    /// </summary>
    /// <param name="ctrl">該当のコントロール</param>
    /// <returns>キー</returns>
    [Description("このコントロールに割り当てたいショートカットキーを設定・取得します")]
    [DefaultValue(typeof(Keys), "None")]
    public Keys GetShortcutKeys(Control control)
    {
        return GetKeysByControl(control);
    }

    /// <summary>
    /// ショートカットキーの設定
    /// </summary>
    /// <param name="ctrl">該当のコントロール</param>
    /// <param name="value">割り当てられたキー</param>
    [Description("このコントロールに割り当てたいショートカットキーを設定・取得します")]
    public void SetShortcutKeys(Control control, Keys shortcutKey)
    {
        //キーがほかに割り当て済みの場合、例外とする
        Control checkCtrl;
        if (extInfo.TryGetValue(shortcutKey, out checkCtrl))
        {
            if (checkCtrl != control)
            {
                throw new ArgumentException("ショートカットキー重複 " + checkCtrl.ToString());
            }
        }
        
        //登録済みの場合削除
        Keys key = GetKeysByControl(control);
        if (key != Keys.None)
        {
            //MAPより削除する
            extInfo.Remove(key);
        }

        //指定されたキーがNone以外の場合、MAPに格納する
        if (shortcutKey != Keys.None)
        {
            extInfo.Add(shortcutKey, control);
        }

    }

    /// <summary>
    /// キーとコントロールの変換
    /// </summary>
    /// <param name="key">コントロール</param>
    /// <returns>対応付けられたショートカットキー</returns>
    private Keys GetKeysByControl(Control control)
    {
        Keys result = Keys.None;
        foreach (Keys key in extInfo.Keys)
        {
            //コントロールからショートカットキーを割り出す
            if (extInfo[key] == control)
            {
                result = key;
                break;
            }
        }

        return result;
    }

    /// <summary>
    /// キー押下イベント
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void TargetForm_KeyDown(object sender, KeyEventArgs e)
    {
        Control control = null;
        if (extInfo.TryGetValue(e.KeyData, out control))
        {
            if (control != null && control.Enabled == true)
            {
                ((Button)control).PerformClick();
            }
        }
        
    }

}


partial class ShortcutKeyProvider
{
    /// <summary>
    /// 必要なデザイナ変数です。
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// 使用中のリソースをすべてクリーンアップします。
    /// </summary>
    /// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region コンポーネント デザイナで生成されたコード

    /// <summary>
    /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
    /// コード エディタで変更しないでください。
    /// </summary>
    private void InitializeComponent()
    {
        components = new System.ComponentModel.Container();
    }

    #endregion
}

2008年9月29日月曜日

[.NET]普通のボタンにショートカットキーを割り当てる

「とあるFormのメニューにある項目をボタンに変更したい。ただしショートカットは使用したい。」

という仕様変更を言い渡されました。まぁ単純に考えると、FormのKeyPreview=Trueに変更して、キーイベントをアレして実装すればよいのですが、ほかに方法がないかと調査してみました。


調べてみたものの、ショートカットのみっていう機能みつからず、あきらめてメニューから項目削除しようとしたところ、Visibleプロパティがあるではないですが。そこで、
  1. 該当のメニューの制御(Enableプロパティの制御)そのままのこす
  2. 該当のメニューのVisible=Falseにする
  3. ボタンのクリックイベントを該当のメニューのクリックイベントに同じメソッドを指定する
  4. ボタンのEnable制御は1.のタイミングで実施する

ということを実装してみました。というかほとんど実装していません。そしてToolTipにそれらしいショートカットーを表示すると、ショートカットの機能する(しているようにみえる)ボタンが完成しちゃいました。
いいやり方とはいえませんが、こんな使い方もできちゃうんですねぇ。

2008年9月27日土曜日

[.NET]クラッシックASP/ASP.NETで情報共有

レガシーASPとASP.NETを共存させたい。または移行などで共存せざるを得ない場合があります。
基本的に両者は別のサービスであるため、情報の共有も簡単ではありません。しかしStateServerというSQLServerを使ったデータ連携を使うと意外と簡単に実現することができます。

従来の ASP と ASP.NET でセッション状態を共有する方法

何かあった場合に備えてメモ。