none
GridView(sql)とTeeView(xml)を使い特定のノードを選択 RRS feed

  • 質問

  • GridViewのレコード(例えばID1のレコード)をクリックするとそれに関するTreeViewのnode(Value=”1”)を選択できるようにしたいのですが、

    どのようなアプローチをすればよいでしょうか?

    漠然と、レコードにボタンをつけてノードを開くコードをレコード分書く。しかしもっと合理的な方法があるのではないかと思ったのですがいかがでしょうか?

    2011年10月6日 0:17

回答

  • > このSelectedIndexChangedをXpathに渡すところができません。

    GridView の[選択]をクリックした時、GridView1_SelectedIndexChanged メソ
    ッドの row.Cells[1].Text で FirstName が正しく取得できているなら、そのメ
    ソッドに以下のコードを追加すればいいと思います。

    PeopleDataSource.XPath = 
        "/People/Person[Name/FirstName='" + row.Cells[1].Text + "']";
    PeopleTreeView.DataBind();
    
    


    ところで、何故、

    > 元はlistitemだったのをやめsqlデータを作りバインドしました

    というようなことをしたのでしょう? GridView も XmlDataSource を使って
    xml ファイルにデータバインドすべきと思いますが。以下のように。

    <asp:XmlDataSource ID="XmlDataSource1" 
        runat="server"
        XPath="/People/Person"
        DataFile="~/App_Data/people.xml">
    </asp:XmlDataSource>
    <asp:GridView ID="GridView1" 
        runat="server" 
        DataSourceID="XmlDataSource1" 
        AutoGenerateColumns="False"
        onselectedindexchanged="GridView1_SelectedIndexChanged">
        <Columns>
            <asp:TemplateField HeaderText="Select">
                <ItemTemplate>
                    <asp:LinkButton ID="LinkButton1" 
                        runat="server" 
                        CommandName="Select" 
                        Text="選択">
                    </asp:LinkButton>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="First Name">
                <ItemTemplate>
                    <asp:Label ID="Label1" 
                        runat="server" 
                        Text='<%# XPath("Name/FirstName") %>'>
                    </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    

    • 回答としてマーク taka_toshi 2011年10月14日 0:47
    2011年10月8日 2:30
  • > formは同時に表示しなくてもいいのですが、、、。

    最初に GridView のページを表示し、ユーザーが選択ボタンをクリックしたら
    TreeView のページに遷移して、ユーザーの選択結果を TreeView に表示する
    ということなら可能です。

    GridView.SelectedIndexChanged イベンのトハンドラで TreeView のページに
    リダイレクトすると共に、クエリ文字列を使って選択したレコードの FirstName
    を渡し、TreeView のページでは Page.Load イベントのハンドラでクエリ文字
    列から FirstName を取得して XmlDataSource.XPath プロパティに設定すると
    いう手順でできそうです。

    ただし、何度も選択やり直すような場合は、GridView/TreeView のページを行
    ったり来たりしなければならず、実用的ではないかもしれません。

     

    • 回答としてマーク taka_toshi 2011年10月14日 0:48
    2011年10月11日 12:15

すべての返信

  • クリックのイベントハンドラで TreeView の TreeNode を検索で
    きるキー情報が取得できれば可能だと思いますが、Web アプリが
    そのような構造になっているか全く不明ですので実際にできるか
    どうかはわかりません。

    とにかく情報が少なすぎです。

    質問を書くときに手を抜かないで、どういう情報を提供すれば回
    答者がやりたいことや問題点を理解できるかをよく考えて、でき
    るだけ詳しく書くようにしましょう。

    2011年10月6日 12:27
  • ありがとうございます。いつもお騒がせしております。

    http://64.4.10.145/ja-jp/magazine/ms178367 TechNetのサンプルに近いものがあったのでTryしてみてるのですが、、、。

    DropDownList(元はlistitemだったのをやめsqlデータを作りバインドしました)とTreeView(元々xmlバインド)で一応動きます。

    リストで項目(ここでは名前)を選択するとし、treeviewでその人のtreeが選択されます。

    これをGridViewでやりたく、commndofield(選択)を追加し、選択されたレコードをラベルで確認するところまではできたのですが、

    このSelectedIndexChangedをXpathに渡すところができません。

    どうかよろしくお願いします。

    <%@ Page Language="C#" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <script runat="server">
    void SelectName(object sender, EventArgs e)
    {
        if (RegionDropDownList.SelectedValue == "Show All")
        PeopleDataSource.XPath = "/People/Person";
      else
      {
        string SelectedValue = "";
        switch (RegionDropDownList.SelectedValue)
        {
            case "Manoj":
                SelectedValue = "Manoj";
            break;
            case "Jared":
            SelectedValue = "Jared";
            break;
          default:
            break;
        }
        PeopleDataSource.XPath = "/People/Person[Name/FirstName='" + SelectedValue + "']";
      }
      PeopleTreeView.DataBind();
    }
    void GridView1_SelectedIndexChanged(Object sender, EventArgs e)
    {
        GridViewRow row = GridView1.SelectedRow;
        Message.Text = "You selected " + row.Cells[1].Text + ".";
    }

    </script>
     
    <html xmlns="http://www.w3.org/1999/xhtml" >
      <head id="Head1" runat="server">
        <title>ASP.NET Example</title>
    </head>
    <body>
        <form id="form1" runat="server">
          <table border="1" cellpadding="3">
            <tr>
              <td valign="top">
                <b>Select Region:</b>
                <asp:DropDownList runat="server" id="RegionDropDownList" AutoPostBack="True"
                                  OnSelectedIndexChanged="SelectName"
                      DataSourceID="SqlDataSource1" DataTextField="FirstName"
                      DataValueField="FirstName">                             
                </asp:DropDownList>
                  <asp:SqlDataSource ID="SqlDataSource1" runat="server"
                      ConnectionString="<%$ ConnectionStrings:peopleConnectionString %>"
                      SelectCommand="SELECT * FROM [PeopleTB]"></asp:SqlDataSource>
                  <asp:GridView ID="GridView1" runat="server" AllowPaging="True"
                      AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="FirstName"
                      DataSourceID="SqlDataSource1" DataMember="DefaultView"
                      AutoGenerateSelectButton="True"
                      onselectedindexchanged="GridView1_SelectedIndexChanged">
                      <Columns>
                          <asp:BoundField DataField="FirstName" HeaderText="FirstName"
                              SortExpression="FirstName" />
                      </Columns>
                  </asp:GridView>
                  <asp:Label ID="Message" runat="server" Text="Label"></asp:Label>
              </td>
              <td valign="top">
                <asp:XmlDataSource
                  id="PeopleDataSource"
                  runat="server"
                  XPath="/People/Person"
                  DataFile="~/App_Data/people.xml" />
                <asp:TreeView
                  id="PeopleTreeView"
                  runat="server"
                  DataSourceID="PeopleDataSource">
                  <DataBindings>
                    <asp:TreeNodeBinding DataMember="LastName"    TextField="#InnerText" />
                    <asp:TreeNodeBinding DataMember="FirstName"   TextField="#InnerText" />
                    <asp:TreeNodeBinding DataMember="Street"      TextField="#InnerText" />
                    <asp:TreeNodeBinding DataMember="City"        TextField="#InnerText" />
                    <asp:TreeNodeBinding DataMember="Region"      TextField="#InnerText" />
                    <asp:TreeNodeBinding DataMember="ZipCode"     TextField="#InnerText" />
                    <asp:TreeNodeBinding DataMember="Title"       TextField="#InnerText" />
                    <asp:TreeNodeBinding DataMember="Description" TextField="#InnerText" />
                  </DataBindings>
                </asp:TreeView>
              </td>
            </tr>
          </table>
        </form>
      </body>
    </html>

    people.xmlデータ

    <?xml version="1.0" encoding="utf-8" ?>
    <People>
      <Person>
        <Name>
          <FirstName>Manoj</FirstName>
          <LastName>Syamala</LastName>
        </Name>
        <Address>
          <Street>345 Maple St.</Street>
          <City>Redmond</City>
          <Region>CA</Region>
          <ZipCode>01434</ZipCode>
        </Address>
        <Job>
          <Title>CEO</Title>
          <Description>Develops company strategies.</Description>
        </Job>
      </Person>

      <Person>
        <Name>
          <FirstName>Jared</FirstName>
          <LastName>Stivers</LastName>
        </Name>
        <Address>
          <Street>123 Elm St.</Street>
          <City>Seattle</City>
          <Region>WA</Region>
          <ZipCode>11223</ZipCode>
        </Address>
        <Job>
          <Title>Attorney</Title>
          <Description>Reviews legal issues.</Description>
        </Job>
      </Person>
    </People>

    2011年10月7日 6:40
  • > このSelectedIndexChangedをXpathに渡すところができません。

    GridView の[選択]をクリックした時、GridView1_SelectedIndexChanged メソ
    ッドの row.Cells[1].Text で FirstName が正しく取得できているなら、そのメ
    ソッドに以下のコードを追加すればいいと思います。

    PeopleDataSource.XPath = 
        "/People/Person[Name/FirstName='" + row.Cells[1].Text + "']";
    PeopleTreeView.DataBind();
    
    


    ところで、何故、

    > 元はlistitemだったのをやめsqlデータを作りバインドしました

    というようなことをしたのでしょう? GridView も XmlDataSource を使って
    xml ファイルにデータバインドすべきと思いますが。以下のように。

    <asp:XmlDataSource ID="XmlDataSource1" 
        runat="server"
        XPath="/People/Person"
        DataFile="~/App_Data/people.xml">
    </asp:XmlDataSource>
    <asp:GridView ID="GridView1" 
        runat="server" 
        DataSourceID="XmlDataSource1" 
        AutoGenerateColumns="False"
        onselectedindexchanged="GridView1_SelectedIndexChanged">
        <Columns>
            <asp:TemplateField HeaderText="Select">
                <ItemTemplate>
                    <asp:LinkButton ID="LinkButton1" 
                        runat="server" 
                        CommandName="Select" 
                        Text="選択">
                    </asp:LinkButton>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="First Name">
                <ItemTemplate>
                    <asp:Label ID="Label1" 
                        runat="server" 
                        Text='<%# XPath("Name/FirstName") %>'>
                    </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    

    • 回答としてマーク taka_toshi 2011年10月14日 0:47
    2011年10月8日 2:30
  • ありがとうございました。無事動作しました。いつもすみません。

    > 元はlistitemだったのをやめsqlデータを作りバインドしました

    これは今作っているのがGridviewとSqlのもので(以前何度か質問させていただいた)、参考にしたサンプルを現状に近づけるためでした。

    これにTreeviewと連携させたかったのです。

    そこで初歩的な質問で恐縮なのですが、GridviewとTreeviewを別formに作った場合、” 'TreeView1、xmlDatasource' は現在のコンテキスト内に存在しません。” となりますがどのようにしたらよいでしょうか?すみません。

     

    2011年10月8日 7:00
  • > そこで初歩的な質問で恐縮なのですが、GridviewとTreeviewを別formに
    > 作った場合、” 'TreeView1、xmlDatasource' は現在のコンテキスト内
    > に存在しません。” となりますがどのようにしたらよいでしょうか?

    GridView と TreeView を別ページに配置したらしいのは想像できますが、
    相変わらず情報不足でわかりません。具体的にどのようにしたのか書いて
    ください。

     

    2011年10月8日 9:02
  • > そこで初歩的な質問で恐縮なのですが、GridviewとTreeviewを別formに
    > 作った場合、” 'TreeView1、xmlDatasource' は現在のコンテキスト内
    > に存在しません。” となりますがどのようにしたらよいでしょうか?

    GridView と TreeView を別ページに配置したらしいのは想像できますが、
    相変わらず情報不足でわかりません。具体的にどのようにしたのか書いて
    ください。

     

    すみません、、、。上述したサンプルの場合ですが、Form1にGridView、Form2にTreeViewを配置しForm1.csに

     protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            GridViewRow row = GridView1.SelectedRow;
            XmlDataSource1.XPath =
           "/People/Person[Name/FirstName='" + row.Cells[1].Text + "']";
            TreeView1.DataBind();

    としコードを実行すると、、” 'TreeView1、xmlDatasource' は現在のコンテキスト内に存在しません。”と出ます。

    以下がコードです。すみません。よろしくお願いします。

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Form1.aspx.cs" Inherits="Form1" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        </div>
        <asp:GridView ID="GridView1" runat="server" AllowPaging="True"
            AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="id"
            DataSourceID="SqlDataSource1"
            onselectedindexchanged="GridView1_SelectedIndexChanged">
            <Columns>
                <asp:BoundField DataField="id" HeaderText="id" ReadOnly="True"
                    SortExpression="id" />
                <asp:BoundField DataField="FirstName" HeaderText="FirstName"
                    SortExpression="FirstName" />
                <asp:CommandField ShowSelectButton="True" />
            </Columns>
        </asp:GridView>
        <asp:Label ID="Label1" runat="server"></asp:Label>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server"
            ConnectionString="<%$ ConnectionStrings:peopleConnectionString %>"
            SelectCommand="SELECT * FROM [PeopleTB]"></asp:SqlDataSource>
        </form>
    </body>
    </html>

    public partial class Form1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
        protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            GridViewRow row = GridView1.SelectedRow;
            XmlDataSource1.XPath =
           "/People/Person[Name/FirstName='" + row.Cells[1].Text + "']";
            TreeView1.DataBind();
        }
    }


    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Form2.aspx.cs" Inherits="Form2" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        </div>
        <asp:TreeView ID="TreeView1" runat="server" DataSourceID="XmlDataSource1">
        </asp:TreeView>
        <asp:XmlDataSource ID="XmlDataSource1" runat="server"
            DataFile="~/App_Data/people.xml"></asp:XmlDataSource>
        </form>
    </body>
    </html>

    2011年10月10日 2:26
  • ひょっとして Windows アプリのように、Form1 と Form2 を同時に表示して、Form1
    の GridView の選択ボタンを切り替えることによって Form2 の TreeView を連動し
    て切り替えることを考えてますか?

    それは Web アプリではできません。最初の例のように 1 ページに表示するのが良い
    と思います。

    何故できないかは、ごくごく基本的なことなので自分で勉強して、Windows アプリと
    Web アプリの違いを理解できるようになってください。でないと、掲示板では話が通
    じません。

    なお。

    > ” 'TreeView1、xmlDatasource' は現在のコンテキスト内に存在しません。”

    というのもごく基本的なことです。Form2 に配置した TreeView1、xmlDatasource は
    Form1 からは参照できません。このあたりも勉強が必要と思います。

     

    2011年10月10日 9:47
  • ありがとうございます。やっぱりそうですか。いろいろ探してみてもwindowsのformに関するものはあるのですが、webに関するのものがなかなか見当たらなくて。

    formは同時に表示しなくてもいいのですが、、、。

    TreeViewが展開したとき画面の半分くらいになり、GridViewも画面いっぱいなので何とかならないものかなと、、、。

    なにか施策などないでしょうかねえ、、、。

    2011年10月10日 23:52
  • > formは同時に表示しなくてもいいのですが、、、。

    最初に GridView のページを表示し、ユーザーが選択ボタンをクリックしたら
    TreeView のページに遷移して、ユーザーの選択結果を TreeView に表示する
    ということなら可能です。

    GridView.SelectedIndexChanged イベンのトハンドラで TreeView のページに
    リダイレクトすると共に、クエリ文字列を使って選択したレコードの FirstName
    を渡し、TreeView のページでは Page.Load イベントのハンドラでクエリ文字
    列から FirstName を取得して XmlDataSource.XPath プロパティに設定すると
    いう手順でできそうです。

    ただし、何度も選択やり直すような場合は、GridView/TreeView のページを行
    ったり来たりしなければならず、実用的ではないかもしれません。

     

    • 回答としてマーク taka_toshi 2011年10月14日 0:48
    2011年10月11日 12:15
  • いろいろと探してやってみてるですが、、、Webページ間ポスティング、cookie、server trancefer、session、、、。

    サンプルで、ページ1のtextboxにテキスト入力してコマンドボタンを押し、ページ2のtextboxに表示させるというのはできたのですが、、。

    SurferOnWwwさんの助言とサンプルを参考にし現在以下のようになっています。素人ながら結構いい線まで言ってると思うのですが、、、。

    よろしくお願いします!

    DataGridがある送る側のページ:

     protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
        {

         GridViewRow row = GridView1.SelectedRow;
            Response.Redirect("~/Page2.aspx?XPath=/People/Person[Name/FirstName='" + row.Cells[1].Text + "']");
        }

    TreeViewがある受ける側のページ:

     protected void Page_Load(object sender, EventArgs e)
        {

    String s = Request.QueryString["XPath"];

     XmlDataSource1.XPath = s;
                TreeView1.DataBind();

     

    2011年10月13日 10:12
  • それでよさそうですが、どういう問題が出るのでしょうか?

     

    2011年10月13日 14:14
  • すみません、動きました!

    いろいろサンプルが入っていて煩雑になっていたので、新たに作り直したところ上記のコードで無事に動きました。

    いつもお付き合いくださってありがとうございます。

    これに懲りずまたよろしくお願いします。

    2011年10月14日 0:47