2

誰かが助けてくれることを願っています。長年の 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;
    }

私の現在のソリューションでは、サブノードのサブノードを含むツリービューを取得しますが、それらは間違っている/重複が多いなどです。上記のおそらく複雑すぎる試みを修正するために文字通り何日も費やしましたが、結論に達しましたおそらく間違った方法でそれを行っています。

どんな助けでも大歓迎です!

4

2 に答える 2

0

より論理的な方向性を教えてくれた hman に感謝します。LDAPPath を辞書キーとして使用しました。

Dictionary<String, AssignmentData> OUDictionary = new Dictionary<String, AssignmentData>();

//Read from DB
cmd = new SqlCommand("SELECT UserGroups.UserGroupID, UserGroups.Name, UserGroups.LDAPPath FROM UserGroups WHERE UserGroups.TypeID=1", DBCon);
            reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                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,
                        };
                UserOUDictionary.Add(reader[2].ToString(), newItem);

            }
            reader.Close();
            reader.Dispose();


            //Now Read OU List into TreeView Collection
            foreach (AssignmentData d in UserOUDictionary.Values)
            {
                String parentKey = GetParentLDAPPath(d.AssignmentLDAPPath);
                if (UserOUDictionary.ContainsKey(parentKey))
                {
                    AssignmentData parentItem = UserOUDictionary[parentKey];
                    if (parentItem.Children == null) { parentItem.Children = new ObservableCollection<AssignmentData> { d }; } //add first child
                    else { parentItem.Children.Add(d); } //add more children to exisiting
                }
                else
                {
                    UserOUCollection.Add(d); //add to root of control
                }
            }


private String GetParentLDAPKey(String strLDAPPath)
    {
        String retParentKey = strLDAPPath;
        if (strLDAPPath.Contains(","))
        {
            retParentKey = retParentKey.Replace("LDAP://", "");
            retParentKey = retParentKey.Remove(0, retParentKey.IndexOf(",") + 1);
            retParentKey = "LDAP://" + retParentKey;
        }

        return retParentKey;
    }
于 2013-11-04T17:25:37.870 に答える