テーマの適用と解除
MSDNフォーラムでテーマの適用と解除の話題がありました。
せっかくなので調べたことをまとめておきます。
○.cssと.skin
テーマでは.cssファイルと.skinファイルを利用することができます。.cssファイルには通常のスタイルシートによる設定を記述します。.skinファイルにはコントロールに対するプロパティの記述の形式で設定を記述することができます。
○StyleSheetThemaとTheme
テーマを適用する際、StyleSheetThemaとThemeの2つの適用方法があります。この適用方法には以下の違いがあります。
・.cssファイルの場合
.cssファイルの場合はStyleSheetThemaとThemeに違いはありません。どちらを利用しても、cssファイルがページのヘッダーの部分で読み込まれるようになります。
・.skinファイルの場合
.skinファイルに記述した設定はコントロールに組み込まれることになります。
StyleSheetThemaを利用したばあい、最初に.skinファイルの内容がコントロールに設定され、その後コントロール自体の持つプロパティの設定で上書きされます。
Themaを利用した場合、最初にコントロール自体の持つプロパティの内容がコントロールに設定され、その後.skinファイルの内容で上書きされます。
同じプロパティにそれぞれ異なる設定を記述した場合、下記の関係が成り立つと考えればよいと思います。
Thema > プロパティ > StyleSheetThema
○テーマの一括設定
テーマを個々のページに設定する場合はPageディレクティブに属性として設定します。しかし、通常はWebアプリケーション全体でテーマを利用するという場合が多いでしょう。このような場合、web.configに記述することですべてのページに同一のテーマを適用することができます。
<system.web>
<pages theme="Thema1" />
</system.web>
この場合web.configの記述によって設定の有効範囲を変えることができます。
たとえば、フォルダ毎にweb.configを作成し、それぞれに別のテーマを設定することでフォルダ単位でテーマを切り替えることができます。またlocationを利用することで特定のファイル(やフォルダ)のテーマを切り替えるということも可能です。
○テーマの部分解除
テーマが一括設定されている場合、特定のページでそのテーマを解除する場合はテーマに空文字を設定します。
Theme=""
StyleSheetThemaを利用している場合はStyleSheetThemaに空文字を設定します。
ページディレクティブにはEnableTheming属性があり、ドキュメントにはこの属性にfalseを設定するとテーマを使用しない、と記述されていますが、この場合Themaとして設定された.skinファイルが使用されないだけです。
.cssファイルは必ず使用されてしまいますし、StyleSheetThemaとして設定された.skinファイルも使われてしまいます。
この点、ちょっと注意が必要ですね。
TreeViewで現在のノードだけを展開する
TreeViewで階層が深いSiteMapを表示しているとき、現在のページが含まれるノードだけを展開して表示したいということがあります。
こういった場合にはTreeViewのPreRenderイベントで以下のようなプログラムを記述してみましょう。
protected void TreeView1_PreRender(object sender, EventArgs e)
{
foreach (TreeNode tn in this.TreeView1.Nodes)
{
checkURL(tn);
}
}
private bool checkURL(TreeNode tn)
{
bool rtn = false;
tn.Expanded = false;
foreach (TreeNode tnc in tn.ChildNodes)
{
if (checkURL(tnc))
{
rtn = true;
tn.Expanded = true;
}
}
if (tn.NavigateUrl.ToLower() == Context.Request.FilePath.ToLower())
{
rtn = true;
}
return rtn;
}
checkURLでは再帰を利用していてロジックが少しわかりにくくなっていますが、以下の作業を行っています。
・すべてのノードを閉じる
・ノードの持つURLとブラウザからリクエストされたURLを比較する。
・URLが一致したノードから親としてたどれるすべてのノードを展開する。
このプログラムを利用する場合、注意する点はTreeViewのExpandDepthプロパティに値を設定してはいけないという点です。ExpandDepthプロパティに値が設定されている場合、初期のTreeView内部にはその値に応じたノードしか存在しないため、上記のプログラムが正常に作動しないことになってしまいます。
ちなみに、TreeViewではノードの展開や縮小はJavaScriptを利用して行われており、ある種Ajax的な実装が標準となっています。