저는 일련의 질문을 바탕으로 문제 해결 가이드로 사용할 첫 번째 웹 페이지에서 작업 해 왔습니다. 질문은 이전 질문의 답으로 결정되므로 "자신의 모험을 선택하십시오"로 바뀝니다. 운 좋게 가능한 모든 경로를 보여주는 결정 흐름 차트가 주어졌지만 도쿄 지하철지도처럼 보입니다. 처음에는 일련의 패널을 만들었습니다. 각 패널에는 질문과 대답을 포함하는 드롭 다운 목록 컨트롤과 텍스트를 포함하고 패널의 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;
}
}
FindControl 메서드를 수행 할 때 System.Web.Page를 참조합니다. – Kevin
실제로 패널과 같은 웹 컨트롤에서 FindControl 함수를 호출 할 수 있습니다. 그 특별한 통제. 전체 페이지를 검색하지 않을 때 실제로 더 빠를 것입니다. 그러나 BuildGraph에서 전달한 "패널 ID"문자열에 대한 참조를 찾고 있으므로 실제 패널 참조를 대신 전달할 수 있습니다. – nvuono