gpt4 book ai didi

WPF TreeView 的 C# Observable 集合 LDAP 路径子项

转载 作者:太空宇宙 更新时间:2023-11-03 13:34:07 27 4
gpt4 key购买 nike

我希望有人能提供帮助。一个长期的 Windows 窗体/aspx 用户,转向 WPF。

不期待对此有一个编码答案,但是任何关于不同方法的指示都将不胜感激 - 我可能正在以一种非常落后的方式来解决这个问题。

所以目标是有一个 ObservableCollection,其中包含子 ObservableCollection“childen”,然后绑定(bind)到我的 WPF TreeView 控件。

我可以毫无问题地将我的集合绑定(bind)到 TreeView ,并根据需要使用复选框图像设置样式,令人沮丧的是,它是 ObservableCollection 与 child 的 child 的 child ,我首先无法生成。

我在 SQL 中有一个包含 LDAP 路径的表,以及我针对该 LDAP 路径存储的各种其他信息,我将这些信息读入我的 ObservableCollection。

单一级别,没问题,我正在努力解决的问题是按 LDAP 路径对子对象的子对象进行排序,因此当我绑定(bind)到 TreeView 时,会显示为 AD OU 的结构。

如:

  • 顶级OU

    • 用户

      • 前台用户

      • 服务台用户

我的数据库中的示例 LDAP 路径

LDAP://OU=Front Office Users,OU=Users,OU=TopOU,DC=dev,DC=local

LDAP://OU=Helpdesk Users,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;
}

使用我当前的解决方案,我得到了一个 TreeView ,其中包含子节点的子节点,但它们是错误的/大量重复等。我花了几天时间试图修复我上面可能过于复杂的尝试 - 但得出了结论我可能以错误的方式处理它。

非常感谢任何帮助!

最佳答案

只是细读 ;) 通过您的代码。想我能明白为什么你有很多重复。看起来您的第一个 SQL 查询获取了所有父/子记录。然后第二个查询将再次获取其中一些记录,如果这有意义的话。

一种方法是在您的第一个查询中只获取顶级项目。可能通过让 SQL 计算逗号的数量。

SELECT UserGroups.UserGroupID, UserGroups.Name, UserGroups.LDAPPath, 
LENGTH(LDAPPath) - LENGTH(REPLACE(LDAPPath, ',', '')) as CommaCount
FROM UserGroups
WHERE UserGroups.TypeID=1
AND CommaCount = 2

既然你问了不同的方法,id 说在循环中重复查询数据库不是很有效。当我构建一棵父子对象树时,我通常会在一个查询中获取所有父/子记录。构建所有对象的平面字典。然后遍历它并建立父/子关联。

字典也可用于稍后直接通过键查找对象或循环查找对象,而无需创建爬行树的递归函数。

所以我建议您将其分解为 2 个代码块。

第一 block :使用获取所有项的现有查询,创建一个包含所有内容的平面字典。

他们每个项目的键应该是 GetLDAPHierarchical() 的结果。

第二 block :接下来遍历字典并创建层次结构。将没有父级的任何东西直接添加到 UserOUCollection

foreach(AssignmentData d in myDictionary.Values)
{
String parentKey = GetParentLDAPKey(d.AssignmentLDAPHierarchical);

if (myDictionary.ContainsKey(parentKey))
{
myDictionary(parentKey).children.Add(d);
}
else
{
UserOUCollection.Add(d);
}
}

GetParentLDAPKey() 需要通过删除 LDAP 路径的第一部分来生成与其父项相同的 key 。

希望这能为您指明正确的方向。

H

(粉碎)

关于WPF TreeView 的 C# Observable 集合 LDAP 路径子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19278760/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com