FC2ブログ
日々の開発でぶち当たった疑問解消のプロセスを残していきます。

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
-------- : スポンサー広告 :
Pagetop

[ASP.NET MVC3] フォームタグを使用したモデルバインディング

モデルバインディングの機構

ASP.NET MVC3ではユーザが入力した値をアクションメソッドが簡単に受け取ることができるように、モデルバインディングと呼ばれる機構がアクションメソッドの呼出し前に動作します。 モデルバインディングを実行するのはSystem.Web.Mvc.IModelBinderの実装クラスで、既定ではSystem.Web.Mvc.DefaultModelBinderクラスが適用されます。 DefaultModelBinderクラスは内部で登録されているSystem.Web.Mvc.IValueProviderを使用して、実際にモデルバインディングを実行していきます。 IValueProviderの既定実装は以下の4つです。 (MVC3からChildActionValueProviderもあるけどあまり公の資料には存在しないので放置)

データの取得元 使用するIValueProviderの実装型
Request.Form System.Web.Mvc.FormValueProvider
RouteData.Values System.Web.Mvc.FormValueProvider
Request.QueryString System.Web.Mvc.QueryStringValueProvider
Request.Files System.Web.Mvc.HttpFileCollectionValueProvider

DefaultModelBinderは、これらのIValueProviderを使ってモデルバインディングを実行しています。

モデルバインディングの実装例(フォーム)

Request.Formとのモデルバインディングの例を挙げていきます。 Request.Formから取得できる値は、WebブラウザからPOSTされたフォームのデータです。 Request.Formのキーはinputタグのname属性値が使用されます。 以下に簡単な例を示します。 他のIValueProviderを使用する例はまたの機会に。。。

ビュー(HTMLタグで記述する場合)

@using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
    <div>
        <input type="text" name="sample" />
    </div>
    <div>
        <input type="submit" value="テスト" />
    </div>
    <div>
        @ViewBag.Message
    </div>
}
    

コントローラー

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult Test(string sample)
    {
        this.ViewBag.Message = sample;
        return this.View();
    }
}
    

ボタンを押下すると、ビューのフォームにあるname属性がsampleであるテキストボックスに入力した値がアクションメソッドの第1引数に渡されます。 name属性の値と、同じ名前のアクションメソッドの仮引数に入力された値をバインドしてくれます。

HtmlHelperを使うと、ビューにHTMLのinputタグを書かなくても良くなります。 同じアクションメソッドを使う場合、ビューは以下のように書くこともできます。

ビュー(HtmlHelperを使用する場合)

@using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
    <div>
        @Html.Editor("sample")
    </div>
    <div>
        <input type="submit" value="テスト" />
    </div>
    <div>
        @ViewBag.Message
    </div>
}
    

どちらの場合もビューのテキストボックスに入力した値をアクションメソッドで取得できていることが確認できます。

次に、モデルクラスを作成してバインドする例を示します。 同じように入力された値をモデルクラスのオブジェクトにバインドしてみます。

モデルクラス

namespace MVC3Sample
{
    public class TestModel
    {
        public string Sample { get; set; }
    }
}
    

ビュー(HtmlHelperとモデルクラスを使用する場合)

@model MVC3Sample.TestModel
@using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
    <div>
        @Html.EditorFor(model => model.Sample)
    </div>
    <div>
        <input type="submit" value="テスト" />
    </div>
    <div>
        @ViewBag.Message
    </div>
}
    

コントローラー

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult Test(TestModel model)
    {
        this.ViewBag.Message = model.Sample;
        return this.View(model);
    }
}
    

上記の例ではアクションメソッドにTestModelオブジェクトが引き渡され、そのSampleプロパティにビューに入力した値が設定されます。

フォームタグのモデルバインディングにはまだまだ他の機能があります。 配列やリストにもバインドできます。 ディクショナリにバインドすることもできます。 このあたりも別稿にできたら、と言うことで後回しにしてしまいます。

落とし穴

さて、これで一見どのような方法でも同じようにモデルバインドできているように見えます。 しかし実際には大きな落とし穴があるのです。 それを確認するために以下のモデル、ビュー、コントローラーを実装してみます。

モデル

namespace MVC3Sample
{
    public class TestModel
    {
        public string TestInput1 { get; set; }
        public string TestInput2 { get; set; }
    }
}
    

ビュー

@model MVC3Sample.TestModel
@using (Html.BeginForm("Test", "Home", FormMethod.Post))
{
    <div>
        @Html.EditorFor(model => model.TestInput1)
    </div>
    <div>
        <input type="text" name="TestInput2" />
    </div>
    <div>
        @Html.Editor("TestInput3")
    </div>
    <div>
        <input type="text" name="TestInput4" />
    </div>
    <div>
        <input type="submit" value="テスト" />
    </div>
    <div>
        <p>@this.ViewBag.Message1</p>
        <p>@this.ViewBag.Message2</p>
        <p>@this.ViewBag.Message3</p>
        <p>@this.ViewBag.Message4</p>
    </div>
}
    

コントローラー

[HttpPost]
public ActionResult Test(
    TestModel model,
    string TestInput3,
    string TestInput4)
{
    ViewBag.Message1 =
        GetMessage(
            "HtmlHelperからカスタムクラスへのバインド",
            model.TestInput1);
    ViewBag.Message2 =
        GetMessage(
            "素のHTMLからカスタムクラスへのバインド",
            model.TestInput2);
    ViewBag.Message3 =
        GetMessage(
            "HtmlHelperから文字列へのバインド",
            TestInput3);
    ViewBag.Message4 =
        GetMessage(
            "素のHTMLから文字列へのバインド",
            TestInput4);
    return this.View(model);
}

private static string GetMessage(
    string name,
    string value)
{
    if (value == null)
    {
        return name + "の値は null でした。";
    }
    else if (string.IsNullOrEmpty(value))
    {
        return name + "の値は 空文字 でした。";
    }
    else
    {
        return name + "の値は " + value + " でした。";
    }
}
    

各テキストボックスに適当に値を入力して実行すると、正しくモデルバインドされる様子を確認できます。 しかし、すべてのテキストボックスを未入力状態にしてボタンを押下してみてください。 なぜか上2つのバインド結果はnull参照になってしまいます。

null 参照になってしまう例

この動作はDefaultModelBinderの仕様によって決まっているように見えます。 あまり深追いはしていないのですが、IModelBinderの実装クラスを入れ替えるのは至難の業なので、こういう仕様になってしまうんだということを認識しておいた方がよいかと思います。 私はてっきり空文字がバインドされるものだと思っていて、カスタムクラスへのバインドで見事にはまりました。

ちなみに、Request.Form["TestInput1"]を取得すると空文字になっています。 なんとなくASP.NET MVC3 Frameworkのバグに見えてしまうのですが。。。 ともかくカスタムクラスにバインドする場合はnullがバインドされる可能性を十分に考慮してコーディングするのが現状の対応策でしょう。 モデルクラスのプロパティの実装で、nullが返却されないようにするなどの対応は考慮しておいた方がよさそうですね。

参考:モデルバインディングのカスタマイズ

既定のIValueProvider実装クラスは全てsealedに設定されているため、独自の機能をこれらのクラスに追加することはできません。 よってモデルバインディングの機構に独自の処理を追加するにはIValueProviderの実装クラスを自分で作成する必要があります。 もちろんIModelBinderを実装することも可能ですが、ASP.NET MVC Frameworkのアップデートに楽に対応したいならIValueProviderを実装したほうがよいと思います。

IValueProviderのインスタンスは、System.Web.Mvc.ValueProviderFactory抽象クラスの実装クラスによって生成されます。 よって既定のIValueProviderにも、それぞれ対応するValueProviderFactoryの実装クラスが存在します(System.Web.MVC名前空間にいます。詳細は割愛。)。

ValueProviderFactoryのインスタンスはSystem.Web.Mvc.ValueProviderFactories静的クラスが管理しています。 このクラスのFactoriesプロパティから、DefaultModelBinderが使用するValueProviderFactory実装クラスのインスタンスを取得できます。 逆に言うと、モデルバインディングをカスタマイズしたい場合は以下のステップを踏むことになります。

  1. IValueProviderの実装クラスを作成する
  2. ValueProviderFactoryの実装クラスを作成して、上記IValueProviderのインスタンスを返すように実装する
  3. Global.asaxのApplication_Startで、ValueProviderFactories.Factoriesに上記ValueProviderFactoryのインスタンスを生成して登録する

このような実装をおこなうことで、モデルバインディングの機構をカスタマイズすることができます。 IValueProviderの実装方法についてはいつか別稿でかければいいな。

スポンサーサイト
2012-01-25 : 未分類 : コメント : 0 : トラックバック : 0
Pagetop

[ASP.NET MVC3] AJAXを使用した部分更新

まずはサンプルの通りに実装してみる

ASP.NET MVC3とAJAXを組み合わせて部分更新をしようと思った際にはまったのでメモです。 環境は以下の通り。

  • Visual Studio 2010 SP1
  • ASP.NET MVC3
  • ビューエンジンはRazor

とっかかりに「ASP.NET MVCで認証、テスト、フィルタ機能、AJAXを活用しよう」をみながらサンプルを実装してみました。 まずはVisual StudioでASP.NET MVC3のテンプレートを使ってプロジェクトを作成します。 (MVC3のテンプレートならどれでも同じ結果になりますが、いろいろ作るのが面倒なのでインターネット用のを今回は使いました。)

続いてビューにAjaxHelperを使ってフォームとリンクを作ります。 これもサンプルと同じ感じで実装します。

@using (Ajax.BeginForm("GetDateTime", new AjaxOptions()
{
    UpdateTargetId = "DateTimeSpan"
}))
{
    <input type="submit" value="更新" />
}
@Ajax.ActionLink("更新", "GetDateTime", new AjaxOptions()
{
    UpdateTargetId = "DateTimeSpan"
})
<div>
    <p>
        現在時刻:<span id="DateTimeSpan"></span>
    </p>
</div>

次にコントローラの実装です。 これもサンプルと同じように、stringを返すアクションメソッドを作成します。

public string GetDateTime()
{
    // 確認のために1秒スリープします。
    System.Threading.Thread.Sleep(1000);
    return DateTime.Now.ToString();
}

サンプルではここまで実装して実行すると部分更新が実現できる、となっています。 しかし、MVC3のテンプレートではこのまま実行しても部分更新は実行されません。 実際に実行してみると、GetDateTimeメソッドの戻り値の表示されるページに遷移してしまいます。 これはBeginFormでレンダリングしたボタンであっても、ActionLinkでレンダリングしたアンカータグでも同様です。

サーバサイドから目的の値を取得することができているので、問題は部分更新を実現する部分にあることは明白です。 ASP.NET Web Formを使用した場合、部分更新を実現する最も簡単な方法はUpdatePanelを使用した方法です。 このとき、おまじないのように配置していたScriptManagerコントロールが、部分更新まわりのJavaScriptをまとめて公開してくれていましたが、AP.NET MVC3ではそのような便利コントロールはありません。 ASP.NET MVC3で部分更新を行うためには、テンプレートを適用した際に一緒に入ってくるjQueryのスクリプトを使用します。

プロジェクトを作成した際に自動的に出力される[Scripts]フォルダに対象のJavaScriptが入っています。 jquery.unobtrusive-ajax.js(またはjquery.unobtrusive-ajax.min.js)がそれです。 名前の通り、中身の実装はjQueryのライブラリに依存していますので、併せてjQuery本体のJavaScriptファイルも参照します。

既定では、HTMLのヘッダ部分はレイアウトファイルに記載されます。 プロジェクトルートから[Views]-[Shared]フォルダの中に_Layout.cshtmlファイルがあります。 これが既定のレイアウトファイルです。 このファイルのヘッダを以下のように設定します。

<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
</head>

jQuery本体は私の環境では1.5.1が入っているのでそうなっていますが、環境に合わせて書き換えてください。

ここまで実装できたら再度実行してみてください。 今度は正しく部分更新が実行されるように見えるはずです。

ハイパーリンクが正しく動かない

さて、一見正しく動作しているように見えますが、ハイパーリンクのタグを数回クリックしてみてください。 最初の1回は正しく部分更新されている様子が見えますが、2回目以降は日時が更新されません。 ハイパーリンク→ボタン→ハイパーリンクの順でクリックすると、1回目のハイパーリンククリックで取得した値に2回目のハイパーリンククリックで戻ってしまう様が確認できるかと思います。

これはハイパーリンクの方のHTTPメソッドに原因があります。 レンダリングされたHTMLを確認してみるとわかりますが、カスタムのタグはあるものの基本的にはただのアンカータグが出力されていると思います。

<a data-ajax="true"
    data-ajax-mode="replace"
    data-ajax-update="#DateTimeSpan"
    href="/Home/GetDateTime">
    更新
</a>

通常ブラウザはただのアンカータグからはHTTP GETのメソッドを使用してアクセスを行います。 また取得した値はブラウザ内でキャッシュを獲得するように動作します。 そのため、2回目のクリックではブラウザ内のキャッシュがそのまま使用され、最初にクリックした値が再表示されてしまうわけです。 すなわちサーバサイドにリクエストを投げることもしません。 なお、この動作はブラウザの設定によって異なる可能性がありますので、正しく動作してしまう場合はブラウザのキャッシュの設定を確認ください。

この動作を変更するには、HTTP GETメソッドによるデータの取得から、POSTメソッドによる取得に変更する必要があります。 Ajax.ActionLinkメソッドの呼び出し部分に、さらに1行追加してPOSTメソッドによるデータ取得を行うよう変更します。

@Ajax.ActionLink("更新", "GetDateTime", new AjaxOptions()
{
    HttpMethod = "POST",
    UpdateTargetId = "DateTimeSpan"
})

この状態で再度実行してみると、ボタンを押下しても、ハイパーリンクを押下しても同じ結果が得られるようになると思います。

2012-01-17 : ASP.NET MVC3 : コメント : 1 : トラックバック : 0
Pagetop

[JavaScript]入力された文字列のふりがな取得

テキストボックスに入力された文字列のふりがなを取得するには

UI要件でたまーに出くわす入力補助系の要件に、入力された文字列のふりがなを自動的に隣のテキストボックスに入れる、なんていうのがあると思います。たまにそういったことを実現しているWebサイトを見かけますよね。というわけで早速先人たちの知恵をお借りしようと検索してみました。

どうもこの話が話題になってきたのは2005年ころ。そして2008年ころからまた話題が再燃して多くの方たちがこの問題にチャレンジされてきた形跡がうかがえます。一番多く紹介されているのがAutoRuby.jsという名前のもののようです。

実際にこのスクリプトを適用してみると、ちゃんとふりがながしゅとくできちゃいます。おーすごい!

AutoRuby.jsの問題点

精度の問題については仕方ない点もありますし、とやかく言う立場にはありませんので触れません。

ちょっと調べてみると、このたぐいのスクリプトはprototype.jsが前提になっているものが多いわけです。AutoRuby.jsもprototype.jsの上に構築されています。私の担当しているプロジェクトはASP.NETです。そう、やっぱりjQueryにのっておきたいと思ってしまうわけですよ。。。実際に既にjQuery UIのライブラリを使用しているので、prototype.jsを持ってくるのはやっぱりリスキーです。jQueryのアップデート時に面倒な作業を作りたくありませんし、余計なテストもしたくないですしね。

というわけでjQueryを使っていても動作するAutoRuby.jsみたいなものを探してみることにしました。

jquery.auto_ruby.js

まずjQueryのプラグイン形式で使用可能なスクリプトとしては jquery.auto_ruby.jsを発見しました。オプションもいくつかあるので割と柔軟に使えます。実装自体はAutoRuby.jsをjQueryに書き直したものらしいです。

kanaTextExtension.js

続いてjQueryにもprototype.jsにも依存しないライブラリであるkanaTextExtension.jsをご紹介します。 こちらのライブラリは完全に素のJavaScriptで作られていますので、ライブラリに依存することなく使用できるというメリットがあります。またオプションもいくつか提供されていますので設定変更もある程度は柔軟に対応できるようです。

その他の方法

JavaScriptでの実装は、基本的に変換が確定する前に入力されているひらがな状態の文字列を取得する、という方法になっています。そのため、ひらがなまじりの文字列を変換した場合、どうしてもうまく取得できないといった問題にぶち当たります。またうまく対処できているように見えても、文字の削除などに対応するのはほぼ不可能、というのが現状です。IMEにアクセスしているわけではないので当然これ以上のことはできないわけです。

変換前の文字列を横取りする方法はお手軽に実装できる半面、精度には問題があるわけです。この問題点を解消する方法は、入力されている文字列からひらがなへ逆変換する方法が考えられます。ActiveXなんかが使える環境であればIMEを呼び出して元に戻してあげるように実装することも可能でしょう(この実装については保障されませんし、実際動作させることができるかかなり微妙なところですが・・・)。

あとはWebサービスを使ってサーバサイドで逆変換することも可能です。かな漢字まじりの文字列をひらがなに変換するのは主にIMEと考えてしまいますが、サーバサイドでIMEを呼び出すのは一般的にNGです。Officeをサーバサイドで使ってはいけないのと同様、IMEもユーザ操作を伴うことが前提となって実装さているため、サーバサイドで呼び出すのはNGというわけです(MSへ問い合わせてみたところそう言われました。)。

残された方法は形態素解析のエンジンをサーバサイドで動かし、そこでひらがなへの変換を行ってもらうという方式です。多くの形態素解析エンジンはIMEと同様自分で辞書定義を拡張することが可能です。人名や地名、商品名などの固有名詞のふりがなを取得する場合、一般的な形態素解析エンジンはうまく形態素解析をすることができませんが、辞書を拡張することで可能になるものがほとんどです。 ここに漢字かな対応表にのようなデータベース(データを運用時に積み重ねていくようなものを作る)を組み合わせればかなり精度を上げることができるかと思います。 ただし、当然JavaScriptで動作させるよりレスポンスが悪くなりますので、どちらを選択するかはケースバイケース、ということになるでしょう。

結論

ただの入力補助として考えるならフリーのJavaScriptを適用して素直にやろう。 レスポンスより精度が求められるならサーバサイドで変換の方式を検討しよう。

2011-10-10 : JavaScript : コメント : 0 : トラックバック : 0
Pagetop

[Reflector]最後の無償版(.NET Reflector 6.8)リリース

今更ですが、Reflector最後の無償リリースされていました

2010年末ごろから次のバージョンでは無償版を提供しないとかするとか、いろいろごたごたしてたReflectorの最新版がリリースされました。最終的には無償版もしっかり提供するということで落ち着いたようです。有償版はバージョン7、無償版はバージョン6.8としてリリースされています。ひとまずReflectorが有償版のみにならなくて良かった。。。やっぱりいざというとき便利ですよね。

以下にリンクを張っておきます。 えらく深いところに無償版のサポートページがあるので探すのに苦労しました。。。
.NET Reflector 6 Community Forum forum

以下にサポートフォーラムの内容を適当に訳してのせておきます。

.NET Reflector 6.8が利用可能になりました

Greg.Tillman 2011/05/11 の投稿

.NET Reflectorの最後の無償版である.NET Reflector6(バージョン6.8)は、前までの無償版と異なり有効期限が切れたり、アップデートを強制もしません。 利用するには.NET Reflector6のライセンスを登録する必要があります。

.NET Reflector 6はバージョン6.でリリースした.NET Reflectorのスタンドアロンバージョンと同じ機能を持ちます。Visual Studioのアドイン、またはデバッグ機能を含んでいません。私たちは、Reflectorの将来のバージョンについて、ユーザが最新の情報を取得するための「ようこそ画面」を加えました。.NET Reflector 6はバグフィックスや、バージョン7で使用可能になる新機能を含んでいません。

.NET Reflector 6は既存の無償版Reflectorユーザが自動アップデートの仕組みを通してのみ使用可能です。別々にダウンロードすることはできません。

.NET Reflector バージョン6.8へのアップデート方法

バージョン6.6を使用している多くの方たちは以下の手順に従ってアップデートしてください。

  • .NET Reflector 6.xを起動すると、有効期限切れか、もうすぐ有効期限が切れることを警告として通知します
  • Reflectorの最後の無償版であることを示す警告を無視します
  • 更新または(バージョン7の)トライアル版をダウンロードするか尋ねるメッセージにすべて「はい」とクリックしてください
  • この時点では.NET Reflector 6.8がダウンロードできます

この代替として、.NET Reflector のヘルプメニュー内にある「更新を確認」を使用して、バージョン6.8をダウンロードすることもできます。

最近.NET Reflector 6.7 にアップデートしている場合、6月末に表示される有効期限切れのメッセージを待つこともできますし、今日バージョン6.8にアップデートすることもできます。

ライセンスの登録とアクティベーション

あなたはライセンンス登録を完了させ、.NET Reflector 6のコピーをアクティベートしなければなりません。これは最初の14日間であれば、.NET Reflector起動後またはヘルプメニューから実施することができます。

登録するために

  • .NET Reflector 6.8をすでに起動している場合、ヘルプメニューをクリックします
  • 「Register」をクリックします
  • 有効なメールアドレスを入力します
  • 誓約書に同意し、チェックします
  • 「Continue」をクリックします
  • Reflector 6のシリアルキーが入力したメールアドレス宛に送られてきます(メールが届くまで最大30分くらいお待ちください)

アクティベートするために

  • .NET Reflector 6.8をすでに起動している場合、ヘルプメニューをクリックします
  • 「Activate」をクリックします
  • 送られてきたシリアルキーを入力します
  • 「Activate」をクリックします
  • Reflector 6のアクティベートが成功したという通知を受け取ることができます

1つのシリアルキーで、すでに.NET Reflector 6のコピーがインストールされている最大5台のマシンのReflectorをアクティベートすることができます。ヘルプメニューの関連オプションを使用することで、いつでもアクティベートしたり、アクティベートを解除したりすることができます。

登録せずに14日間.NET Reflector 6を使用することができます。登録時に入力していただいたメールアドレスは他の場所で要求されない限りマーケティング目的には使用されません。

Reflector6.6 を他のマシンで使用するための詳細は、以下のフォーラムの投稿を参照してください。

http://www.red-gate.com/messageboard/viewtopic.php?t=13384

2011-06-11 : .NET 開発 : コメント : 1 : トラックバック : 1
Pagetop

[Silverlight4]入力可能なコンボボックスを作る

Silverlightには入力可能なコンボボックスがない

すでに多くの方々が直面してきたこの話題、今更ながら自分もぶち当たったので備忘録として残します。

WPFならComboBox.IsEditableプロパティをtrueに設定すれば簡単に書き込み可能なコンボボックスが作れますが、Silverlightの場合はこいつが常にfalseを返す読み取り専用プロパティとして実装されています。しかもオーバーライドもできません。なので全部自分で実装しないと書き込み可能なコンボボックスを使うことができません。

どうやって作るか

私が最終的に採用したのはSilverlight SDKに入っているAutoCompleteBoxと、ToggleButtonを組み合わせる方法。他にも普通のコンボボックスを拡張する方法などいろいろやり方はあると思うのですが、最終的に実装する際のインタフェースが一番しっくりくる、という理由でこの方法を選択しました。Google先生に質問するといろいろ答えてくれるので、その他の方法についてはあまり触れません。

実はAutoCompleteBoxとToggleButtonを組み合わせる方法もWebを検索するといくつか出てきます。その中でも私が採用したオススメはCreating a ComboBox Style AutoCompleteBox Control in Silverlightで紹介されている方法です。他のサイトで紹介されている方法だと、100%ユーザコントロール化できていないものが多く、使用者からすると「確かに実現できているけど使い方がめんどくさい」という感じの仕上がりになっているものが多いです。こちらのサイトで紹介されている方法だと、かなり直観的な使用感に仕上がっていてGOODです。英語サイトですが、実装例だけを追っかければほとんど問題なく実装できるかと思います。

先ほど紹介したサイトの通りに実装すると、1文字以上入力されたときにオートコンプリートが走るようになります。コントロールのテンプレートにコメントが入っていますが、MinimumPrefixLengthプロパティを0に設定すると、オートコンプリートの働くコンボボックスが出来上がります。

具体的には以下の部分を0に変更します。

<!-- The minimum prefix length should be 0 for combo box scenarios -->
<Setter Property="MinimumPrefixLength" Value="1" />

もう一歩先に進むために

Generic.xamlを使ってテンプレートを作ると、開発者がスタイルを意識して記述する必要もなくなります。カスタムコントロールを作る際はこれを使うとすごく楽にデフォルトのスタイルを作れます。カスタムコントロールを配置したSilverlight クラスライブラリプロジェクトに「themes」フォルダを追加し、その中にGeneric.xamlを配置します。

Generic.xamlを作成する場合、紹介したページのStep2で解説されているテンプレートの記述が多少変わりますので注意してください。詳細は「Generic.xaml」で検索するといろいろ情報が出てきますので参照してください。

2011-06-07 : Silverlight : コメント : 0 : トラックバック : 0
Pagetop
ホーム  次のページ »

プロフィール

masatsuna

筆者:某システム会社のダメSE
競技スキーをこよなく愛するダメSEです。

月別アーカイブ

検索フォーム

ブロとも申請フォーム

この人とブロともになる

QRコード

QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。