我希望有人能帮忙。很长一段时间的 windows forms/aspx 用户,正在迁移到 WPF。
不期待对此的编码答案,但将不胜感激任何以不同方式接近的指针 - 我可能以非常落后的方式接近这个问题。
所以目标是有一个带有子 ObservableCollection“childen”的 ObservableCollection,然后绑定到我的 WPF 树视图控件。
我可以毫无问题地将我的集合绑定到树视图,并根据需要使用复选框图像对其进行样式设置,令人沮丧的是,它的 ObservableCollection 带有我一开始就无法生成的孩子的孩子。
我在 SQL 中有一个带有 LDAP 路径的表,以及我针对该 LDAP 路径存储的各种其他信息,我将这些信息读入我的 ObservableCollection。
单级,没问题,我正在努力的一点是通过 LDAP 路径对子对象的子对象进行排序,所以当我绑定到树视图时,会呈现为 AD OU 的结构化。
例如:
TopOU
用户
前台用户
帮助台用户
我的数据库中的示例 LDAP 路径
LDAP://OU=前台用户,OU=用户,OU=TopOU,DC=dev,DC=local
LDAP://OU=Helpdesk 用户,OU=Users,OU=TopOU,DC=dev,DC=local
LDAP://OU=OU=Users,OU=TopOU,DC=dev,DC=local
LDAP://OU=OU=TopOU,DC=dev,DC=local
private ObservableCollection<AssignmentData> OUTreeAssignmentsCollection = new ObservableCollection<AssignmentData>();
public class AssignmentData : INotifyPropertyChanged
{
public Int32 AssignmentID { get; set; }
public String AssignmentName { get; set; }
public AssignmentTypes AssignmentType { get; set; }
//other stuff....
//For TreeView all sub nodes
public ObservableCollection<AssignmentData> Children { get; set; }
}
然后我开始以一种相当讨厌的方式从我的数据库中读取数据,这就是一切都出错的地方,我可以使用一些指针。
cmd = new SqlCommand("SELECT UserGroups.UserGroupID, UserGroups.Name, UserGroups.LDAPPath FROM UserGroups WHERE UserGroups.TypeID=1", DBCon);
reader = cmd.ExecuteReader();
while (reader.Read())
{
String strLDAPHierarchical = GetLDAPHierarchical(reader[2].ToString());
AssignmentData newItem = new AssignmentData()
{
AssignmentID = Convert.ToInt32(reader[0]),
AssignmentName = reader[1].ToString(),
AssignmentImage = ouIcon,
AssignmentLDAPPath = reader[2].ToString(),
AssignmentCNPath = GetCNFromLDAPPath(reader[2].ToString()),
AssignmentTooltip = GetADSLocationTooltip(reader[2].ToString()),
AssignmentType = AssignmentTypes.UserOU,
AssignmentLDAPHierarchical = strLDAPHierarchical
};
if (strLDAPHierarchical.Contains(","))
{
//Now check all the root nodes exist to continue
String strLDAPHierarchicalCheckPath = strLDAPHierarchical;
String[] SplitLDAPHierarchical = strLDAPHierarchical.Split(new Char[] { ',' });
Int32 reverseI = SplitLDAPHierarchical.Length - 1;
String prevPath = "";
for (int i = 0; i < SplitLDAPHierarchical.Length; i++)
{
String path = SplitLDAPHierarchical[reverseI];
//now check if this node is already there and if not look it up and create it
if (path != "")
{
if (i == 0) { strLDAPHierarchicalCheckPath = path; }
else { strLDAPHierarchicalCheckPath = path + "," + prevPath; }
WriteLog("CHECK:" + strLDAPHierarchicalCheckPath);
LookupItemByLDAPHierarchical(strLDAPHierarchicalCheckPath, newItem);
if (i == 0) { prevPath = path; }
else { prevPath = path + "," + prevPath; }
reverseI = reverseI - 1;
}
}
}
else
{
//is top level object, so create at the root of the collection
UserOUCollection.Add(newItem);
}
添加子项目的功能:-/
internal AssignmentData LookupItemByLDAPHierarchical(String strLDAPHierarchical, AssignmentData fromItem)
{
AssignmentData currentItem = null;
foreach (AssignmentData d in UserOUCollection)
{
if (d.AssignmentLDAPHierarchical == strLDAPHierarchical) { currentItem = d; break; }
if (d.Children != null)
{
currentItem = CheckChildNodesByLDAPHierarchical(d, strLDAPHierarchical);
if (currentItem != null) { break; }
}
}
String strMessage = "null";
if (currentItem != null) { strMessage = currentItem.AssignmentLDAPPath; }
if (currentItem == null)
{
String strWhere = "LDAPPath LIKE 'LDAP://" + strLDAPHierarchical + "%'";
SqlConnection DBCon = new SqlConnection(SQLString);
DBCon.Open();
SqlCommand cmd = new SqlCommand("SELECT UserGroupID, Name, LDAPPath FROM UserGroups WHERE " + strWhere + " AND TypeID=1", DBCon);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
strLDAPHierarchical = GetLDAPHierarchical(reader[2].ToString());
AssignmentData newItem = new AssignmentData()
{
AssignmentID = Convert.ToInt32(reader[0]),
AssignmentName = reader[1].ToString(),
AssignmentImage = ouIcon,
AssignmentLDAPPath = reader[2].ToString(),
AssignmentCNPath = GetCNFromLDAPPath(reader[2].ToString()),
AssignmentTooltip = GetADSLocationTooltip(reader[2].ToString()),
AssignmentType = AssignmentTypes.UserOU,
AssignmentLDAPHierarchical = strLDAPHierarchical
};
String strLDAPHierarchicalCheckPath = strLDAPHierarchical;
foreach (String path in strLDAPHierarchical.Split(new Char[] { ',' }))
{
//now check if this node is already there and if not look it up and create it
if (path != "")
{
strLDAPHierarchicalCheckPath = strLDAPHierarchicalCheckPath.Replace(path + ",", "");
currentItem = LookupItemByLDAPHierarchical(strLDAPHierarchicalCheckPath, currentItem);
if (null == currentItem)
{
UserOUCollection.Add(newItem); //new root item
}
else
{
if (currentItem.Children == null)
{
//add new child
currentItem.Children = new ObservableCollection<AssignmentData> { newItem };
}
else
{
//add more children to exisiting
currentItem.Children.Add(newItem);
}
}
currentItem = null;
}
}
//Find a current Item to add the node to
//currentItem = LookupItemByLDAPHierarchical(strLDAPHierarchical);
}
reader.Close();
reader.Dispose();
DBCon.Close();
DBCon.Dispose();
}
return currentItem;
}
使用我当前的解决方案,我得到了一个树视图,其中包含子节点的子节点,但它们是错误的/有很多重复等。我花了几天时间试图解决我上面可能过于复杂的尝试 - 但得出的结论是可能以错误的方式进行。
非常感谢任何帮助!