מדריך ASP.NET – עבודה עם נתונים: תצוגת Master/Detail

‏ • Sela

לעתים, כאשר יש לנו הרבה מאפיינים במחלקה, לא נרצה להציג את כולם בפקד ה-GridView מאחר וזה יגרום לטבלה המוצגת להיות מאוד רחבה ולא יהיה נוח לעבוד איתה. לכן, נציג בטבלה רק את המאפיינים החשובים.

במקרה כזה שבו לא מוצגים כל מאפייני האובייקט, נרצה אפשרות לסמן שורה בטבלה ולקבל פירוט של כל המאפיינים של האובייקט הנבחר, כולל המאפיינים שלא הוצגו בטבלה. מבנה זה של GridView + פירוט נוסף מכונה “תצוגת Master/Detail”.

במדריך זה נראה כיצד ליצור מסך עם תצוגת Master/Details.

שלב 1 – הכנה

נוסיף מחלקה חדשה בשם Person לפרויקט שלנו (בחירה ב-Add Class מתפריט Project):ASPNET - הוספת מחלקה

נרשום את מבנה המחלקה באופן הבא:

public class Person
{
  public int ID { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string FullName
  {
    get
    {
      return string.Format("{0} {1}", FirstName, LastName);
    }
  }
  public DateTime BirthDate { get; set; }
}

נוסיף עוד מחלקה בשם PersonLogic שתכיל פעולת Select שמחזירה את רשימת האנשים שיוצגו ב-GridView. את רשימת האנשים נוכל לאחזר מבסיס הנתונים, אך לשם ההדגמה אנחנו נשמור אותם ב-Session, לכן נוסיף גם מאפיין למחלקה החדשה שיחזיר רשימה של אנשים.

הקוד של המחלקה PersonLogic יראה כך:

public class PersonLogic
{
  private List<Person> PersonList
  {
    get
    {
      return HttpContext.Current.Session["People"]
        as List<Person>;
    }
    set
    {
      HttpContext.Current.Session["People"] = value;
    }
  }

  public List<Person> SelectPeople()
  {
    if (PersonList == null)
    {
      List<Person> people = new List<Person>();
      for (int i = 0; i < 5; i++)
      {
        people.Add(new Person()
        {
          ID = i,
          FirstName = string.Format("First{0}", i),
          LastName = string.Format("Last{0}", i),
          BirthDate = new DateTime(1980, 10, i + 1),
        });
      }
      PersonList = people;
    }

    return PersonList;
  }
}

נוסיף דף ASPX למערכת שלנו ונוסיף לדף פקד ObjectDataSource. נעדכן את הפקד שיצביע על המתודה שיצרנו במחלקה PersonLogic (שימו לב שהשדה TypeName מכיל את שם ה-Namespace וייתכן שתצטרכו לתקן אותו בהתאם ל-Namespace שלכם):

<asp:ObjectDataSource runat="server" ID="ObjectDataSource1"  
  TypeName="DataDemo.PersonLogic" 
  SelectMethod="SelectPeople"></asp:ObjectDataSource> 

נוסיף לדף פקד GridView ונצביע מתוך ה – GridView על ה – ObjectDataSource. זהו הכיתוב המלא של ה – GridView:

<asp:GridView ID="GridView1" EnableViewState=true runat="server" 
  DataSourceID="myDataSource" AutoGenerateColumns="False">
  <Columns>
    <asp:BoundField DataField="ID" HeaderText="ID" />
    <asp:BoundField DataField="FirstName" 
HeaderText="FirstName"/>
    <asp:BoundField DataField="LastName" 
HeaderText="LastName"/>
    <asp:BoundField DataField="FullName" 
HeaderText="FullName" ReadOnly="True/>
    <asp:BoundField DataField="BirthDate" 
HeaderText="BirthDate"/>
  </Columns
>
</
asp:GridView
>

שלב 2 – הוספת עמודת פקודה (CommandColumn) ל – Grid

נוסיף בתוך הגדרות ה – Grid את העמודה הבאה:

<asp:CommandField ShowSelectButton="true" />

נוסיף גם עיצוב לשורה הנבחרת על מנת להבדיל אותה משאר השורות:

<SelectedRowStyle BackColor="#0099FF" />

כך שהכיתוב של ה – Grid יראה כך:

<asp:GridView ID="GridView2" runat="server" 
  DataSourceID="myDataSource" AutoGenerateColumns="False" 
  DataKeyNames="ID" EnablePersistedSelection="True">
  <Columns>
    <asp:BoundField DataField="ID" HeaderText="ID" 
      HeaderStyle-Width="0px" ItemStyle-Width="0" 
Visible="true" SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" 
      SortExpression="FirstName" />
    <asp:BoundField DataField="LastName" HeaderText="LastName" 
      SortExpression="LastName" />
    <asp:BoundField DataField="FullName" HeaderText="FullName" 
      ReadOnly="True" SortExpression="FullName" />
    <asp:BoundField DataField="BirthDate" HeaderText="BirthDate" 
      SortExpression="BirthDate" />
    <asp:CommandField ShowSelectButton="true" />
  </Columns>
  <SelectedRowStyle BackColor="#0099FF" 
/>
</
asp:GridView
>

שלב 3 – הוספת DetailsView

נפתח את דף ה-ASPX במצב Design, נוסיף לדף פקד DetailsView (מה-Toolbox, תחת קטגוריית Data), ונבחר לפקד את אותו DataSourceID כשל ה – GridView. בתמונה נוכל לראות כיצד לבחור את ה – DataSource:

ASPNET - בחירת DataSource

ע"י לחיצה על Refresh Schema נקבל את אותם השדות כשל ה- GridView:

<asp:DetailsView ID="DetailsView1" runat="server" 
  AllowPaging="True" AutoGenerateRows="False" 
  DataSourceID="myDataSource" Height="50px" Width="125px">
  <Fields>
    <asp:BoundField DataField="ID" HeaderText="ID" 
SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" 
      SortExpression="FirstName" />
    <asp:BoundField DataField="LastName" HeaderText="LastName" />
    <asp:BoundField DataField="FullName" HeaderText="FullName" 
      ReadOnly="True" SortExpression="FullName" />
    <asp:BoundField DataField="BirthDate" HeaderText="BirthDate" 
      SortExpression="BirthDate" />
  </Fields
>
</
asp:DetailsView> 

שלב 4 – סינכרון השורה הנבחרת ב-Grid עם ה-DetailsView

נוסיף שני EventHandlers- האחד עבור השורה הנבחרת (SelectedIndexChanged) ב – GridView:

<asp:GridView ID="GridView2" runat="server" 
  DataSourceID="myDataSource" AutoGenerateColumns="False" 
  DataKeyNames="ID" EnablePersistedSelection="True" 
  OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
  <Columns>
    <asp:BoundField DataField="ID" HeaderText="ID" 
      HeaderStyle-Width="0px" ItemStyle-Width="0" 
Visible="true" SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" 
      SortExpression="FirstName" />
    <asp:BoundField DataField="LastName" HeaderText="LastName" 
      SortExpression="LastName" />
    <asp:BoundField DataField="FullName" HeaderText="FullName" 
      ReadOnly="True" SortExpression="FullName" />
    <asp:BoundField DataField="BirthDate" HeaderText="BirthDate" 
      SortExpression="BirthDate" />
    <asp:CommandField ShowSelectButton="true" />
  </Columns>
  <SelectedRowStyle BackColor="#0099FF" 
/>
</
asp:GridView
>

והשני עבור שינוי העמוד ב – DetailsView:

<asp:DetailsView ID="DetailsView1" runat="server" 
  AllowPaging="True" AutoGenerateRows="False" 
  DataSourceID="myDataSource" Height="50px" Width="125px"
  OnPageIndexChanged="DetailsView1_PageIndexChanged">
  <Fields>
    <asp:BoundField DataField="ID" HeaderText="ID" 
SortExpression="ID" />
    <asp:BoundField DataField="FirstName" HeaderText="FirstName" 
      SortExpression="FirstName" />
    <asp:BoundField DataField="LastName" HeaderText="LastName" />
    <asp:BoundField DataField="FullName" HeaderText="FullName" 
      ReadOnly="True" SortExpression="FullName" />
    <asp:BoundField DataField="BirthDate" HeaderText="BirthDate" 
      SortExpression="BirthDate" />
  </Fields
>
</
asp:DetailsView> 

כעת נכתוב את מימושי המתודות ב-Code Behind של דף ה-ASPX:

protected void GridView1_SelectedIndexChanged(
object sender, EventArgs e)
{
  DetailsView1.SetPageIndex(GridView1.SelectedIndex);
}

protected void DetailsView1_PageIndexChanged(
object sender, EventArgs e)
{
  GridView1.SelectedIndex = DetailsView1.PageIndex;
}

כעת נראה את התוצאות (ע"י הקלקה ימנית על הדף ו – View in Browser):

ASPNET - הצגת GridView ו-DetailsView

נלחץ על המספר 3 למטה ונראה כי גם השורה ב – GridView השתנתה:

ASPNET - הצגת GridView ו-DetailsView

תצוגת Master/Detail יכולה לשמש אותנו להרחבה של המידע המוצג בטבלה, אך היא גם יכולה לשמש אותנו עבור תצוגת מידע נוסף, לדוגמה נוכל להציג טבלה של קטגוריות מוצרים וכשהמשתמש מסמן קטגוריה, להציג לו טבלה נוספת של רשימת המוצרים בקטגוריה. גם תצוגה כזו מכונה תצוגת Master/Detail.

תגיות: , , , ,

IdoFlatow

יועץ ומרצה בקבוצת סלע לתחומי Web ו-Data. עוסק בתחומים Asp.Net, WCF, Silverlight, IIS ו-Entity Framework.כותב הקורס הרשמי של מיקרוסופט ל-WCF וכן שותף בכתיבת הספר ASP.NET Programmer's Reference (ISBN 978-0470505458)

תגובות בפייסבוק