C# 从数据库绑定分层树视图

C# 从数据库绑定分层树视图,c#,wpf,xaml,treeview,hierarchicaldatatemplate,C#,Wpf,Xaml,Treeview,Hierarchicaldatatemplate,我对使用TreeView完全是新手。我的解决方案有两个项目,一个叫做业务层,即从数据库获取数据的类库,另一个叫做实际的WPF应用程序本身 我的系列数据库中有两个非常简单的表,其数据如下: 在我的业务层项目中,我有四个类 1) 儿童模型 public class ChildrenModel { public string Name { get; set; } public int Age { get; set; } public double Income { get;

我对使用TreeView完全是新手。我的解决方案有两个项目,一个叫做业务层,即从数据库获取数据的类库,另一个叫做实际的WPF应用程序本身

我的
系列
数据库中有两个非常简单的表,其数据如下:

在我的业务层项目中,我有四个类

1) 儿童模型

public class ChildrenModel
{
    public string Name { get; set; }
    public int Age { get; set; }
    public double Income { get; set; }
    public string Address { get; set; }
    public int FId { get; set; }
}
2) FamilyModel.cs

public class FamilyModel
{
    public string Name { get; set; }

    public List<ChildrenModel> ChildenData { get; set; }
}
4) 最后使用DataRetrieval.cs从数据库中获取数据。这里我有一个非常简单的存储过程,它基本上结合了
Family
Person

我有以下课程:

public class DataRetrieval
   {
        List<FamilyModel> familyList = new List<FamilyModel>();
        List<ChildrenModel> childList = new List<ChildrenModel>();
        List<FamilyTemp> familyNames = new List<FamilyTemp>();
        using (SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\v11.0; AttachDbFilename=|DataDirectory|\Families.mdf; Integrated Security=True; Connect Timeout=30;"))
        {

            con.Open();
            //int count = 1;
            //int temp = 1;
            SqlCommand cmd = new SqlCommand("sp_GetFamilies", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataReader dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                ChildrenModel cModel = new ChildrenModel();
                cModel.Name = dr["PersonName"].ToString();
                cModel.Age = Convert.ToInt32(dr["PersonAge"]);
                cModel.Address = dr["PersonAddress"].ToString();
                cModel.Income = double.Parse(dr["PersonIncome"].ToString());
                cModel.FId = Convert.ToInt32(dr["FamilyId"]);
                childList.Add(cModel);

            }
            dr.Close();
            SqlCommand cmd1 = new SqlCommand("Select Distinct * from Family", con);
            SqlDataReader dr1 = cmd1.ExecuteReader();
            while (dr1.Read())
            {
                FamilyTemp ft = new FamilyTemp()
                {
                    id = Convert.ToInt32(dr1["Id"]),
                    name = dr1["Name"].ToString()
                };
                familyNames.Add(ft);
            }

            for (int i = 0; i < familyNames.Count; i++)
            {
                FamilyModel fModelResult = new FamilyModel();
                fModelResult.Name = familyNames[i].name;
                foreach (var item in childList.Where(x => x.FId == familyNames[i].id).ToList())
                {
                    fModelResult.ChildenData.Add(item);
                }
                familyList.Add(fModelResult);
            }

        }
        return familyList;

    }

}
公共类数据检索
{
List familyList=新列表();
List childList=新列表();
List familyNames=新列表();
使用(SqlConnection con=newsqlconnection(@“数据源=(LocalDB)\v11.0;AttachDbFilename=| DataDirectory | \Families.mdf;集成安全性=True;连接超时=30;”)
{
con.Open();
//整数计数=1;
//内部温度=1;
SqlCommand cmd=新的SqlCommand(“sp_GetFamilies”,con);
cmd.CommandType=CommandType.storedProcess;
SqlDataReader dr=cmd.ExecuteReader();
while(dr.Read())
{
ChildrenModel cModel=新的ChildrenModel();
cModel.Name=dr[“PersonName”].ToString();
cModel.Age=Convert.ToInt32(dr[“人物]);
cModel.Address=dr[“PersonalAddress”].ToString();
cModel.Income=double.Parse(dr[“PersonIncome”].ToString());
cModel.FId=Convert.ToInt32(dr[“FamilyId]”);
childList.Add(cModel);
}
Close博士();
SqlCommand cmd1=新的SqlCommand(“从族中选择不同的*”,con);
SqlDataReader dr1=cmd1.ExecuteReader();
while(dr1.Read())
{
FamilyTemp ft=新的FamilyTemp()
{
id=Convert.ToInt32(dr1[“id”]),
name=dr1[“name”].ToString()
};
家庭名称。添加(英尺);
}
for(int i=0;ix.FId==familyNames[i].id).ToList()中的var项)
{
fModelResult.childEndData.Add(项目);
}
familyList.Add(fModelResult);
}
}
返回家庭列表;
}
}
现在在主WPF应用程序中,我创建了一个名为TreeViewModel的类,如下所示

public class TreeViewModel:INotifyPropertyChanged
{
    private List<FamilyModel> _familyList;
    public List<FamilyModel> FamilyList
    {
        get
        {
            return _familyList;
        }
        set
        {
            _familyList = value;
            NotifiyPropertyChanged("FamilyList");
        }
    }
    public TreeViewModel()
    {

        FamilyList = DataRetrieval.familyData();
    }



    void NotifiyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
公共类TreeViewModel:INotifyPropertyChanged
{
私人名单(家庭名单),;
公共列表家庭列表
{
得到
{
返回家庭列表;
}
设置
{
_家庭列表=价值;
通知财产变更(“家庭名单”);
}
}
公共树视图模型()
{
FamilyList=DataRetrieval.familyData();
}
作废NotifiyPropertyChanged(字符串属性)
{
if(PropertyChanged!=null)
PropertyChanged(此,新PropertyChangedEventArgs(property));
}
公共事件属性更改事件处理程序属性更改;
}
现在在我的主窗口中,我想要一个上一个图中显示的层次结构。datacontext是TreeViewModel。我应该提到什么样的数据类型,它似乎将数据绑定到treeview。请告诉我我犯了什么错误。我得到了一些错误的输出


我希望树状视图如下所示

public class TreeViewModel:INotifyPropertyChanged
{
    private List<FamilyModel> _familyList;
    public List<FamilyModel> FamilyList
    {
        get
        {
            return _familyList;
        }
        set
        {
            _familyList = value;
            NotifiyPropertyChanged("FamilyList");
        }
    }
    public TreeViewModel()
    {

        FamilyList = DataRetrieval.familyData();
    }



    void NotifiyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
<!--
self namespace is:
xmlns:self="clr-namespace:BusinessLayer;assembly=BusinessLayer"
-->
<Grid>
    <TextBlock Text="Family Tree" Foreground="Red"></TextBlock>
    <TreeView Margin="10" Height="200">
        <HierarchicalDataTemplate ItemsSource="{Binding FamilyList}" DataType="{x:Type self:FamilyModel}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}"></TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>
        <DataTemplate DataType="{x:Type self:ChildrenModel}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}"></TextBlock>
                <TextBlock Text="{Binding Age}"></TextBlock>
            </StackPanel>
        </DataTemplate>

    </TreeView>
</Grid>