誰かが助けてくれることを願っています。長年の Windows フォーム/aspx ユーザーで、WPF に移行しています。
これに対するコード化された回答は期待していませんが、別の方法でアプローチするための指針があれば大歓迎です-私はおそらく非常に後方の方法でこれに取り組んでいます.
したがって、目的は、サブ ObservableCollection の「子」を含む ObservableCollection を作成して、WPF ツリービュー コントロールにバインドすることです。
コレクションを問題なくツリービューにバインドでき、必要に応じてチェックボックスの画像でスタイルを設定しましたが、イライラすることに、そもそも生成に問題がある子の子の子を持つ ObservableCollection です。
LDAP パスを含む SQL のテーブルがあり、その LDAP パスに対して保存しているその他のさまざまな情報を ObservableCollection に読み込みます。
単一レベル、問題ありません。私が苦労しているビットは、サブオブジェクトのサブオブジェクトを LDAP パスでソートすることです。そのため、ツリービューにバインドすると、AD OU が構造化されているように表示されます。
例えば:
トップOU
ユーザー
フロントオフィスユーザー
ヘルプデスク ユーザー
私のDBのLDAPパスの例
LDAP://OU=Front Office Users,OU=Users,OU=TopOU,DC=dev,DC=local
LDAP://OU=ヘルプデスク ユーザー、OU=ユーザー、OU=TopOU、DC=dev、DC=ローカル
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;
}
私の現在のソリューションでは、サブノードのサブノードを含むツリービューを取得しますが、それらは間違っている/重複が多いなどです。上記のおそらく複雑すぎる試みを修正するために文字通り何日も費やしましたが、結論に達しましたおそらく間違った方法でそれを行っています。
どんな助けでも大歓迎です!