質問

カスタムデータソースからの項目のかなり大きなリストを表示する(派生)メニューコントロールがあります。非常に厄介な「無効または選択できないメニュー項目を選択できません」を避けるために、メニューでViewStateを無効にする必要があります。他のコントロールによってポストバックで現在の選択が変更される場合。

残念ながら、メニューのViewStateが無効になっている場合、メニューによって 生成されるポストバックはイベントを発生させません。 ViewStateを有効にすると、OnMenuItemClickイベントが発生します。 ViewStateを無効にすると、OnMenuItemClickは発生しません。困惑しています。

メニューのViewStateをオフのままにする必要があるので、実際のメニューからのポストバックをどのように処理できますか?

この時点で、MenuのLoadイベントを使用し、__ EVENTTARGETを解析してそれがメニューであるかどうかを確認し、そこから進んでいきます。これにより、通常よりも前にポストバックイベントが技術的に処理されますが、それで問題ありません。

より良いアイデアはありますか

役に立ちましたか?

解決 2

問題の本質を突き止めました。 Reflectorを使用すると、実際のポストバックを処理してからイベントを発生させる低レベルメソッドの重要な部分を確認できます。

string str = HttpUtility.HtmlDecode(eventArgument);
...
MenuItem item = this.Items.FindItem(str.Split(new char[] { '\\' }), 0);
if (item != null)
    this.OnMenuItemClick(new MenuEventArgs(item));

ご覧のとおり、MenuEventArgsにはMenuItemが渡されます。現在のItemsコレクションで、受信する投稿データに一致するものが見つからない場合、イベントは発生しません。 ViewStateを無効にすると、メニューにはアイテムがありません(ViewStateを使用して再構築されます)。そのため、イベントは発生しません。

これを回避するために、まだ更新されていないデータを使用して、ロード中にメニューを作成するようにメニューに指示しました(この時点では、最後のリクエストの最後と同じになります)。これは、基本的にViewStateからメニューを再構築するのと同じです。そのため、パフォーマンスなどについて何も悪く感じません。その後、OnMenuItemClickが期待どおりに発生します。最後に、PreRenderの間に、メニューにもう一度再構築するように指示します。これにより、ライフサイクルのポストバック処理部分で発生した変更が反映されます。

これに多くの時間を費やしたので、この情報が他の誰かが同様の状況で役立つことを願っています。

他のヒント

はい、ビューステートを使用してバインドされたコントロールを再配置するか、イベントが発生する前にデータバインドするかを選択できます(Page_Loadは問題ありません)。

Page_PreRenderで常に新規にバインドするとは限りませんが、このポストバックに何も変更がない場合(ページのどこかで変更が発生した場合)、再度バインドする理由はありません。

代わりに、変更する必要があることがわかっている特定のイベントにのみバインドできる場合があります。

Page_Loadでコントロールをsitemapdataに再バインドし、IsPostBackかどうかを確認します。

if (IsPostBack) {
            Menu.DataBind();
}

これは私のために働き、ビューステートを減らします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top