UpdatePanelでasp:TreeViewの選択されたノードがリセットされるのはなぜですか?
-
03-07-2019 - |
質問
2つの UpdatePanels
を含むasp.net 2.0ページがあります。
最初のパネルには TreeView
コントロールが含まれています。3つのビューコントロールでノードを選択すると、2番目の UpdatePanel
の更新のみがトリガーされます。これは正しく動作しています。
更新パネルの外側のページには2つのボタンがあります(前/次)。これらのボタンは、両方のパネルの更新をトリガーします。ボタンの動作は、ツリー内の隣接ノードを選択することです。これらのボタンの1つを初めてクリックすると、予想される動作が得られ、隣接ノードが選択され、両方のパネルが更新されてこの変更が反映されます。
これらのボタンのいずれかをもう一度クリックすると、問題が発生します。ツリービューの選択されたノードは、以前に選択されたノードを覚えているようで、ボタンはこのノードに作用します。したがって、前/次ボタンの動作は、何もしないか、2つ戻ることです。
編集-問題を示すサンプルコード
マークアップ
<asp:UpdatePanel ID="myTreeViewPanel" runat="server">
<ContentTemplate>
<asp:TreeView runat="server" ID="myTreeView" OnSelectedNodeChanged="myTreeView_SelectedNodeChanged">
<SelectedNodeStyle BackColor="#FF8000" />
</asp:TreeView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="myButton" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:UpdatePanel ID="myLabelPanel" runat="server">
<ContentTemplate>
<asp:Label runat="server" ID="myLabel" Text="myLabel"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="myTreeView" EventName="SelectedNodeChanged" />
<asp:AsyncPostBackTrigger ControlID="myButton" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button runat="server" ID="myButton" Text="myButton" OnClick="myButton_Click" />
背後のコード
protected void Page_Load ( object sender, EventArgs e )
{
if ( !IsPostBack )
{
myTreeView.Nodes.Add( new TreeNode( "Test 1", "Test One" ) );
myTreeView.Nodes.Add( new TreeNode( "Test 2", "Test two" ) );
myTreeView.Nodes.Add( new TreeNode( "Test 3", "Test three" ) );
myTreeView.Nodes.Add( new TreeNode( "Test 4", "Test four" ) );
myTreeView.Nodes.Add( new TreeNode( "Test 5", "Test five" ) );
myTreeView.Nodes.Add( new TreeNode( "Test 6", "Test size" ) );
}
}
protected void myTreeView_SelectedNodeChanged ( object sender, EventArgs e )
{
UpdateLabel( );
}
protected void myButton_Click ( object sender, EventArgs e )
{
// here we just select the next node in the three
int index = myTreeView.Nodes.IndexOf( myTreeView.SelectedNode );
myTreeView.Nodes[ index + 1 ].Select( );
UpdateLabel( );
}
private void UpdateLabel ( )
{
myLabel.Text = myTreeView.SelectedNode.Value;
}
ツリーのビューステートが保存されていないようですか?
解決
UpdatePanelコントロールの概要[asp.net] より
UpdatePanelコントロールと互換性のないコントロール
次のASP.NETコントロールは部分ページの更新と互換性がないため、UpdatePanelコントロール内ではサポートされていません。
- TreeViewおよびMenuコントロール。
- ...
他のヒント
AJAX部分ページポストバックについては、隠し入力__ViewStateが更新されないことは正しいと思います。
ユーザーがWebサイト申請フォームのページに戻ったときに、更新パネルでも同じことが起こります。通常の入力によりビューステートが更新されたため、値が再入力されますが、AJAXで更新されたコントロールの状態は記録されないため、デフォルトの状態に戻ります。
これらの2つの関数を追加するだけで、選択したノードをページ独自のビューステートで保存および復元することにより、この問題を修正できます。
protected override object SaveViewState()
{
ViewState["SelectedNodePath"] = myTreeView.SelectedNode.ValuePath;
return base.SaveViewState();
}
protected void Page_PreLoad(object sender, EventArgs e)
{
if (ViewState["SelectedNodePath"] != null)
{
TreeNode node = myTreeView.FindNode(ViewState["SelectedNodePath"].ToString());
if (node != null)
node.Select();
}
}
選択したノードをLoadViewState()内にロードできません。ツリーにはその時点でノードがないためです。 PreLoadで行います。
これをしなければならないのは間違っていると感じるだけです。何か不足していますか?
私はほぼ同様の問題に直面しています。 CheckedNodesコレクションを失います。同じ手法で問題を解決できるとは思いません。アイデアはありますか?
更新:問題を大幅に解決し、いくつかの回避策を使用しました。詳細はこちらをご覧ください: UpdatePanel内のTreeViewの問題-ノードのチェックボックスのチェックおよびチェック解除時のポストバックおよび AJAX UpdatePanel内でTreeViewを使用する