我在思考我正在努力建立的解决方案时遇到了麻烦,也许这里的某个人能够引导我走向正确的方向。
我有一个属于流程流的进程列表,这些进程可能有子节点,而这些子节点可能也有子节点等等。
列表如下所示:
ProcID ChildOFID
1 0 (means no child)
2 1
3 2
4 3
5 3
6 5
正如你所看到的,Proc“3”包含2个孩子,其中一个(5)也有一个孩子(6)。
我想迭代这个列表并在画布上为它们绘制对象。
现在我有以下代码,但它要求我为我想要显示的每个级别编写一个循环。
int prev_location_left = 0;
int prev_location_top = 0;
// Select Last ProcessStep (has no PreID!)
var lastProcess = (from p in processlist
where p.PreID == 0
select p).FirstOrDefault<ProcessStep>();
if (lastProcess != null)
{
create_processStep(lastProcess.ProcessID,
lastProcess.Name,
lastProcess.ProcessTypeID,
(900),
(30),
lastProcess.CummulativeCT,
lastProcess.WaitingTimeActual,
lastProcess.ValueAddTimeActual,
lastProcess.ProcessStepTime);
prev_location_left = 900;
prev_location_top = 30;
}
// Select all the ProcessSteps that are a child of the last(first) one.
var listChilds = (from p in processlist
where p.PreID == lastProcess.ProcessID
select p);
int childscount = listChilds.Count();
int cnt = 0;
foreach (ProcessStep ps in listChilds)
{
create_processStep(ps.ProcessID,
ps.Name,
ps.ProcessTypeID,
(prev_location_left - (150) ),
(30 + (60 *cnt)),
ps.CummulativeCT,
ps.WaitingTimeActual,
ps.ValueAddTimeActual,
ps.ProcessStepTime);
var listChilds2 = (from p in processlist
where p.PreID == ps.ProcessID
select p);
int cnt2 = 0;
foreach (ProcessStep ps2 in listChilds2)
{
create_processStep(ps2.ProcessID,
ps2.Name,
ps2.ProcessTypeID,
(prev_location_left - (300) ),
(30 + (60 *cnt2)),
ps2.CummulativeCT,
ps2.WaitingTimeActual,
ps2.ValueAddTimeActual,
ps2.ProcessStepTime);
var listChilds3 = (from p in processlist
where p.PreID == ps2.ProcessID
select p);
int cnt3 = 0;
foreach (ProcessStep ps3 in listChilds3)
{
create_processStep(ps3.ProcessID,
ps3.Name,
ps3.ProcessTypeID,
(prev_location_left - (450)),
(30 + (60 * cnt2)),
ps3.CummulativeCT,
ps3.WaitingTimeActual,
ps3.ValueAddTimeActual,
ps3.ProcessStepTime);
cnt3 = cnt3 + 1;
}
cnt2 = cnt2 + 1;
}
cnt = cnt + 1;
}
所以需要做的是:
现在,对于每个被发现的孩子,我还需要检查他们是否有孩子,并再次采用相同的逻辑,我无法将其作为一个无限循环。
帮助! :)
答案 0 :(得分:1)
您可以创建递归父/子对象并使用您的视图绑定到它。以下是使用您提供的数据的一个非常基本的示例。
<强> MainPage.xaml中强>
<UserControl x:Class="SilverlightApplication4.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:SilverlightApplication4"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<local:MainPage_ViewModel/>
</UserControl.DataContext>
<Canvas>
<local:RecursiveView DataContext="{Binding RecursiveObject}"/>
</Canvas>
<强> MainPage_ViewModel.cs 强>
public class MainPage_ViewModel
{
public MainPage_ViewModel()
{
List<KeyValuePair<int, int>> collection = new List<KeyValuePair<int, int>>()
{
new KeyValuePair<int,int>(1,0),
new KeyValuePair<int,int>(2,1),
new KeyValuePair<int,int>(3,2),
new KeyValuePair<int,int>(4,3),
new KeyValuePair<int,int>(5,3),
new KeyValuePair<int,int>(6,5)
};
KeyValuePair<int, int> parent = collection.Where(kvp => kvp.Value == 0).First();
collection.Remove(parent);
RecursiveObject recursiveObject = new RecursiveObject()
{
root = parent.Key
};
populateChildren(recursiveObject, collection);
this.RecursiveObject = recursiveObject;
}
public RecursiveObject RecursiveObject
{
get { return recursiveObject; }
set { recursiveObject = value; }
}
private RecursiveObject recursiveObject;
private void populateChildren(RecursiveObject parent, List<KeyValuePair<int, int>> list)
{
List<KeyValuePair<int, int>> children = list.Where(kvp => kvp.Value == parent.root).ToList();
children.ForEach(child => list.Remove(child));
children.ForEach(child =>
{
RecursiveObject newChild = new RecursiveObject() { root = child.Key };
parent.Children.Add(newChild);
populateChildren(newChild, list);
});
}
}
<强> RecursiveObject.cs 强>
public class RecursiveObject
{
public int root { get; set; }
public List<RecursiveObject> Children
{
get { return children; }
set { children = value; }
}
private List<RecursiveObject> children = new List<RecursiveObject>();
}
<强> RecursiveView.xaml 强>
<UserControl x:Class="SilverlightApplication4.RecursiveView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:SilverlightApplication4"
d:DesignHeight="300" d:DesignWidth="400">
<StackPanel Margin="30,0,0,0">
<TextBlock Text="{Binding root}"/>
<ItemsControl ItemsSource="{Binding Children}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:RecursiveView DataContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
输出图片:
我只是在每个孩子的左边放置一个“30”的边距,但你可以将它调整为你想要的任何东西。不确定这是否有帮助,我只是觉得尝试这是一个有趣的挑战:)