
最近苦戦した話 ASP.NET Web Forms Repeaterの入れ子
1. はじめに
お久しぶりです。エンジニアの今井です。
結構前になりますが、自分の拠点がサテライトオフィスに変わりました。
電話も鳴らないし、とてもきれいでエンジニアが働きやすい環境になっており、仕事も捗ります!
w2の新しいサテライトオフィスが気になる人は、井上君が書いたこの記事を是非見てみて下さい!
さて、最近業務中にちょっと苦戦したことがありました。
調べてもあまりしっかりとした解決方法が見つからなかったので、少しは需要があるのでは?
そう思って今回はこんな記事を書いてみたので是非ご覧下さい。
2. 苦戦したポイント
やりたかったことはASP.NET Web FormsでRepeaterを入れ子状態にし、子階層のRepeaterの中で親階層のRepeaterのデータを参照することでした。(入れ子、ネスト、ネスト構造とかとも言われると思います。)一瞬でできると思っていたのですが、割と苦戦してしまったので、忘れないようにという意味も込めて共有しようと思います。(同じようなことを別のソースコードで発見したのは解決した後でした…)
苦戦した理由は、Repeaterを入れ子にすることは単純にRepeaterを2重に書けば問題なかったのですが、子階層のRepeaterの中で親階層のRepeaterのデータを参照する方法が分からなかったからです。
3. 肝心なソースコードは?
例として下記のようなクラスがあるとします。
ParentクラスはプロパティにChildクラスの配列Childrenを持ちます。
public</span> <span class="token keyword def">class</span> <span class="token class-name">Parent</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> Id <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">string</span> Name <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">public</span> Child<span class="token punctuation">[</span><span class="token punctuation">]</span> Children <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword def">class</span> <span class="token class-name">Child</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span> <span class="token keyword">string</span> Id <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">public</span> <span class="token keyword">string</span> Name <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}
表示側ではParentの配列を持つParentsをRepeaterで表示しながら、子階層となるRepeaterの中でChildrenのNameとParentのIdを表示します。
<</span>asp<span class="token punctuation">:</span><span class="token class-name">Repeater</span> ID<span class="token operator">=</span><span class="token string">"rParent"</span> ItemType<span class="token operator">=</span><span class="token string">"Parent"</span> Runat<span class="token operator">=</span><span class="token string">"server"</span><span class="token operator">></span>
<span class="token operator"><</span>HeaderTemplate<span class="token operator">></span>
<span class="token operator"><</span>table<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>HeaderTemplate<span class="token operator">></span>
<span class="token operator"><</span>ItemTemplate<span class="token operator">></span>
<span class="token operator"><</span>tr<span class="token operator">></span>
<span class="token operator"><</span>td<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">%</span>#<span class="token punctuation">:</span> Item<span class="token punctuation">.</span>Id <span class="token operator">%</span><span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>td<span class="token operator">></span>
<span class="token operator"><</span>td<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">%</span>#<span class="token punctuation">:</span> Item<span class="token punctuation">.</span>Name <span class="token operator">%</span><span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>td<span class="token operator">></span>
<span class="token operator"><</span>td<span class="token operator">></span>
<span class="token operator"><</span>asp<span class="token punctuation">:</span><span class="token class-name">Repeater</span> ID<span class="token operator">=</span><span class="token string">"rChild"</span> DataSource<span class="token operator">=</span><span class="token string">"<%# Item.Children %>"</span> ItemType<span class="token operator">=</span><span class="token string">"Child"</span> Runat<span class="token operator">=</span><span class="token string">"server"</span><span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">%</span>#<span class="token punctuation">:</span> Item<span class="token punctuation">.</span>Name <span class="token operator">+</span> DataBinder<span class="token punctuation">.</span><span class="token function">Eval</span><span class="token punctuation">(</span>Container<span class="token punctuation">.</span>Parent<span class="token punctuation">.</span>Parent<span class="token punctuation">,</span> <span class="token string">"DataItem.Id"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">%</span><span class="token operator">></span><span class="token operator"><</span>br<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>asp<span class="token punctuation">:</span>Repeater<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>td<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>tr<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>ItemTemplate<span class="token operator">></span>
<span class="token operator"><</span>FooterTemplate<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>table<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>FooterTemplate<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>asp<span class="token punctuation">:</span>Repeater<span class="token operator">>
DataBinder.Eval(Container.Parent.Parent, "DataItem.id")
と記述することで子階層から親階層のデータを参照することができました。
4. まとめ
思っていた以上に苦戦してしまいましたが、無事やりたいことは実現できました。これからも実際にエンジニアとして働いている中で、つまづいたり工夫したことがあればどんどん記事にしていきたいと思います!