2009-06-09 3 views
1

저는 일련의 질문을 바탕으로 문제 해결 가이드로 사용할 첫 번째 웹 페이지에서 작업 해 왔습니다. 질문은 이전 질문의 답으로 결정되므로 "자신의 모험을 선택하십시오"로 바뀝니다. 운 좋게 가능한 모든 경로를 보여주는 결정 흐름 차트가 주어졌지만 도쿄 지하철지도처럼 보입니다. 처음에는 일련의 패널을 만들었습니다. 각 패널에는 질문과 대답을 포함하는 드롭 다운 목록 컨트롤과 텍스트를 포함하고 패널의 ID는 미리 있어야합니다. 다음으로 모든 패널을 그래프 구조로 구성하는 클래스를 만들었습니다. 이 클래스를 통해 어떤 패널을 선택했는지, 어떤 패널을 선택하지 않았는지, 그리고 결정 흐름을 쉽게 변경할 수있는 순서를 알 수 있습니다.asp.net에서 일련의?가있는. 제점 해결 웹 페이지 작성. Directed Graph

다음은 pageload 이벤트의 클래스를 사용하는 실제 클래스의 예입니다.

asp.net에 익숙하지 않아서이 문제를 해결하고 코드에 결함이있는 경우 더 좋은 방법이 있는지 궁금합니다. 코드가 작동하지만 개선이있을 수 있습니다. 여기

protected void Page_Load(object sender, EventArgs e) 
{ 

    DecisionGraph g = new DecisionGraph(this); 

    // Pass is root panel 
    g.BuildGraph("pnl1"); 

    // Refreshes graph and returns an obj containing 2 iterable objects 
    DecisionGraphEnumeration dgEnum = g.RefreshGraph(); 

    // Clear panel which will hold active panels 
    pnlMASTER.Controls.Clear(); 

    IEnumerator<Panel> iEnumOnPath = dgEnum.GetOnPathPanelEnumerator(); 
    while (iEnumOnPath.MoveNext()) 
    { 
     Panel p = (Panel)iEnumOnPath.Current; 
     p.Visible = true; 

     pnlMASTER.Controls.Add(p); 
    } 

    IEnumerator<Panel> iEnumOffPath = dgEnum.GetOffPathPanelEnumerator(); 

    while (iEnumOffPath.MoveNext()) 
    { 
     iEnumOffPath.Current.Visible = false; 
    } 
} 

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 
using System.Collections; 
using System.Collections.Generic; 


public class DecisionGraph 
{ 

    const String NULL_POINTER_NAME = "null"; 
    private Node root; 
    private Page webPage; 

    //constructor 
    public DecisionGraph(Page pg) 
    { 
     this.webPage = pg; 
     this.root = null; 
    } 

    // method creates a graph structure recursively starting 
    // with the parameter as root 
    public void BuildGraph(String pnlName) 
    { 
     // return the reference of the supplied panel 
     Panel p = GetPanel(pnlName); 

     // create root 
     root = new Node(p, GetDropDownList(p)); 

     // add children nodes to root 
     insert(root); 


     return; 
    } 

    // adds all child nodes to passed node 
    private void insert(Node n) 
    { 
     // if Panel has a DropDownList 
     if (n.dropDownList != null)// not leaf 
     { 
      // create an array of Nodes to hold references to children 
      n.children = new Node[n.dropDownList.Items.Count]; 

      int i = 0; 
      foreach (ListItem it in n.dropDownList.Items) 
      { 
       Panel childPanel = GetPanel(it.Value); 

       if (childPanel == null) 
       { 
        // Panel does not exit 
        n.children[i] = null; 
       } 
       else 
       { 

        Node childNode = GetNode(childPanel); 

        if (childNode == null)// Node doesn't exist in structure for chilePanel 
        { 
         // create child node 
         childNode = new Node(childPanel, GetDropDownList(childPanel)); 

         // add child node to arryay of children 
         n.children[i] = childNode; 

         // add the childs nodes of childNode to childNode 
         insert(n.children[i]); 
        } 
        else 
        { 
         // node had already been created, just add reference 
         n.children[i] = childNode; 
        } 



       } 

       i++; 
      } 
     } 

     return; 

    } 

    // returns an iterator of all active panels set as visible 
    // and sets all other panels as hidden 
    public DecisionGraphEnumeration RefreshGraph() 
    { 
     LinkedList<Panel> pathedPanels = new LinkedList<Panel>(); 
     LinkedList<Panel> nonPathedPanels = new LinkedList<Panel>(); 

     FindCurrentPath(root, pathedPanels); 

     HideNonPathedNodes(root, nonPathedPanels); 

     UnMarkAllNodes(root); 

     return new DecisionGraphEnumeration(pathedPanels.GetEnumerator(), nonPathedPanels.GetEnumerator()); 
    } 

    // marks each node as valid and saves reference inorder 
    private void FindCurrentPath(Node n, LinkedList<Panel> list) 
    { 
     if (n == null) 
      return; 

     n.visitedFlag = true; 
     list.AddLast(n.panel); 

     if (n.dropDownList == null) 
      return; 

     int index = n.dropDownList.SelectedIndex; 

     FindCurrentPath(n.children[index],list); 

     return; 

    } 

    // finds all non pathed nodes and saves reference in no order 
    private void HideNonPathedNodes(Node n, LinkedList<Panel> list) 
    { 
     if (n == null) 
      return; 

     if (!n.visitedFlag) 
     { 

      n.ResetDropDownList(); 

      // add panel if not already added. 
      if (!list.Contains(n.panel)) 
       list.AddLast(n.panel); 
     } 

     if(n.children == null) 
      return; 

     foreach (Node childNode in n.children) 
      HideNonPathedNodes(childNode, list); 
    } 

    // unmarks n and sets all children of n as unmarked 
    private void UnMarkAllNodes(Node n) 
    { 
     if (n == null) 
      return; 

     n.visitedFlag = false; 

     if (n.children == null) 
     { 
      return; 
     } 
     else 
     { 
      foreach (Node childNode in n.children) 
       UnMarkAllNodes(childNode); 
     } 

    } 

    // returns node if a node already exists for p in structure, else returns null 
    private Node GetNode(Panel p) 
    { 
     Node n = getNode(root, p); 

     return n; 
    } 

    // recursive method call for GetNode 
    private Node getNode(Node n, Panel p) 
    { 
     if (n == null || p == null) 
      return null; 

     if (n.panel.Equals(p)) 
     { 
      return n; 
     } 
     else if (n.children != null) 
     { 
      Node x = null; 
      int i = 0; 

      while (x == null && i < n.children.Length) 
      { 
       x = getNode(n.children[i], p); 
       i++; 
      } 

      return x; 
     } 
     else 
     { 
      return null; 
     } 

    } 

    // returns a DropDownList from p 
    private DropDownList GetDropDownList(Panel p) 
    { 

     foreach (Control ctrl in p.Controls) 
     { 
      if (ctrl is DropDownList) 
      { 
       return (DropDownList) ctrl; 
      } 
     } 

     return null; 
    } 

    // returns a panel from webpage of contructor using the FindControl method 
    private Panel GetPanel(String panelName) 
    { 
     if(panelName.Equals(NULL_POINTER_NAME)) 
      return null; 

     Control ctrl = webPage.FindControl(panelName); 
     if (ctrl is Panel) 
     { 
      return (Panel)ctrl; 
     } 
     else 
     { 
      throw new ArgumentException(String.Format("{0} is not a Panel inside page {1}",panelName,webPage.Title.ToString())); 
     } 
    } 


    private class Node 
    { 
     public Panel panel; 
     public DropDownList dropDownList; 
     public Node[] children; 
     public bool pathedNode; 
     public bool visitedFlag; 

     #region Constructors 

     public Node() : this(null, null) { } 

     public Node(Panel p) : this(p, null) { } 

     public Node(Panel pnl, DropDownList d) 
     { 
      this.panel = pnl; 
      this.dropDownList = d; 
      this.children = null; 
      this.pathedNode = false; 
      this.visitedFlag = false; 
     } 

     #endregion 

     public void ResetDropDownList() 
     { 
      if (dropDownList == null) 
       return; 
      else 
       dropDownList.SelectedIndex = 0; 
     } 
    } 
} 


public class DecisionGraphEnumeration 
{ 
    private IEnumerator<Panel> onPathPanels; 
    private IEnumerator<Panel> offPathPanels; 

    internal DecisionGraphEnumeration(IEnumerator<Panel> active, IEnumerator<Panel> nonActive) 
    { 
     onPathPanels = active; 
     offPathPanels = nonActive; 
    } 

    public IEnumerator<Panel> GetOnPathPanelEnumerator() 
    { 
     return onPathPanels; 
    } 

    public IEnumerator<Panel> GetOffPathPanelEnumerator() 
    { 
     return offPathPanels; 
    } 


} 

답변

1

당신은 당신이 고도로 사용자 정의을 허용 WizardControl http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.wizard.aspx 사용하여 조사 할 수 있습니다 생각 수행 할 작업의 아이디어에 코드를 통과하지만 기반으로하지 않는 클래스입니다 생성 될 마법사

첫 번째 단계에서는 ActiveStepChanged 이벤트를 사용하여 각 단계에서 사용자가 대답하는 내용에 따라 이동할 단계를 결정할 수 있습니다.

0

DecisionGraph 클래스 내에서 System.Web.Page의 인스턴스를 참조하지 말 것을 강력히 권장합니다. 지금 당신이 무엇이든을 위해 참고를 사용하고있는 것처럼 보이지 않으며 당신은 거기에서 그것을 남겨 두는 동안 불필요하게 그것을 사용하기 위하여 유혹 될 것이다.

각 page_load에 대한 전체 그래프를 만드는 것처럼 보입니다. 포스트 백 이후에 구조를 탐색하고 있습니까?

패널의 가시성 속성을 false로 설정하면 클라이언트 측에서 출력이 나오지 않습니다. 그러나 CSS 스타일 속성 "display"를 "none"으로 설정하면 전체 그래프를 클라이언트에 렌더링하고 클라이언트 측에서 javascript로 모든 탐색을 실제로 수행 할 수 있습니다.

+0

FindControl 메서드를 수행 할 때 System.Web.Page를 참조합니다. – Kevin

+0

실제로 패널과 같은 웹 컨트롤에서 FindControl 함수를 호출 할 수 있습니다. 그 특별한 통제. 전체 페이지를 검색하지 않을 때 실제로 더 빠를 것입니다. 그러나 BuildGraph에서 전달한 "패널 ID"문자열에 대한 참조를 찾고 있으므로 실제 패널 참조를 대신 전달할 수 있습니다. – nvuono

관련 문제