C# 如何实现包含父项和子项的组合框层次结构?
这篇文章的标题可能需要一些工作,但我很难在不深入细节的情况下表达自己 这就来了 我有一个简单的WPF应用程序,它从第三方API检索C# 如何实现包含父项和子项的组合框层次结构?,c#,wpf,combobox,C#,Wpf,Combobox,这篇文章的标题可能需要一些工作,但我很难在不深入细节的情况下表达自己 这就来了 我有一个简单的WPF应用程序,它从第三方API检索州、城市、综合区和建筑的列表 公共类状态 { 公共int Id{get;set;} 公共字符串名称{get;set;} } 公营城市 { 公共int Id{get;set;} public int ParentId{get;set;}//FK to Id处于状态 公共字符串名称{get;set;} } 公共类综合体 { 公共int Id{get;set;} publi
州
、城市
、综合区
和建筑
的列表
公共类状态
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公营城市
{
公共int Id{get;set;}
public int ParentId{get;set;}//FK to Id处于状态
公共字符串名称{get;set;}
}
公共类综合体
{
公共int Id{get;set;}
public int ParentId{get;set;}//FK到城市中的Id
公共字符串名称{get;set;}
}
公共班级大楼
{
公共int Id{get;set;}
public int ParentId{get;set;}//FK到复数中的Id
公共字符串名称{get;set;}
}
当填充一些数据时,这些列表可能看起来像这样
StateOptions=新的ObservableCollection
{
新州(){Id=1,Name=“California”},
纽约州(){Id=2,Name=“纽约”},
};
CityOptions=新的可观测集合
{
新城(){Id=1,ParentId=1,Name=“洛杉矶”},
纽约市(){Id=2,ParentId=2,Name=“纽约市”}
};
ComplexOptions=新的可观察收集
{
新复合体(){Id=1,ParentId=1,Name=“洛杉矶国际机场”},
新复合体(){Id=2,ParentId=2,Name=“约翰·F·肯尼迪国际机场”}
};
BuildingOptions=新的ObservableCollection
{
新建建筑(){Id=1,ParentId=1,Name=“Terminal 1”},
新建建筑(){Id=2,ParentId=1,Name=“Terminal 2”},
新建建筑(){Id=3,ParentId=1,Name=“Terminal 3”},
新建建筑(){Id=4,ParentId=2,Name=“Terminal 1”},
新建建筑(){Id=5,ParentId=2,Name=“Terminal 2”},
新建建筑(){Id=6,ParentId=2,Name=“Terminal 3”},
};
使用这些列表,我需要创建一个新对象,Foo
,然后将其发布回API
公共类Foo
{
公共int Id{get;set;}
公共int StateId{get;set;
公共int-CityId{get;set;
公共int复杂{get;set;
public int BuildingId{get;set;
}
这本身非常简单,因为您可以将列表放在四个可观察的集合中,并使用它们作为四个ComboBox
元素的ItemSource
绑定。然后您可以为每个组合框使用SelectedItem
绑定属性来创建Foo
对象
如果这些是简单的列表,那么这就很好了,但是请注意城市
中的ParentId
字段、复杂
和建筑
模型
因此,这四个列表必须被视为一个层次结构。事实上,名称ParentId
非常容易引起误解,因为它们没有引用相同类型的另一个实体。当查看Foo
类时,这一点就很明显了,该类具有上述所有内容的外键
因此,我需要过滤城市组合框中的项目,以仅显示Id等于状态组合框中选定项的父Id的项目。对于复杂组合框和建筑组合框也是如此
为了进一步说明这一点,我更愿意通过创建WPF用户控件来解决这个问题,因为这四个列表将在未来的许多视图中再次出现,并且需要相同的功能。但是,我对所有解决方案都持开放态度。我也更愿意这样做,而不需要额外访问API,因为列表非常大
为方便起见,我在创建了一个演示项目。该项目通过将四个列表视为平面来说明问题,因此,您可以选择洛杉矶国际机场作为综合体,即使纽约被选为该州。这显然是错误的,正是我希望防止用户发现的错误奥林
如果您还有其他问题,请留下评论。经过一番讨论和尝试,我们找到了一些解决此问题的方法 在大多数情况下,第一种解决方案就足够了,而且可能是most推荐的,因为它很容易在视图模型中用最少的逻辑实现,从而强制使用XAML实现层次结构 然而,我又添加了两个解决方案,因为很多人可能也考虑过这些。事实上,我们最终采用了第三个解决方案,因为第一个解决方案不考虑孤儿,除非您将每个孤儿添加为每个项目的子项 解决方案1(推荐) 正如Sheridan所建议的,您可以构建一个层次数据模型,将
节点
变成层次节点
。这可能是最简单的解决方案,如果可以的话,我可能会建议您使用此解决方案
公共类节点
{
公共int Id{get;set;}
public int ParentId{get;set;}
公共字符串名称{get;set;}
}
公共类层次结构节点
{
公共int Id{get;set;}
public int ParentId{get;set;}
公共列表子项{get;set;}
}
从这里,您可以将您的列表
绑定为第一个组合框的项源
。然后,您将第二个组合框的项源
设置为第一个组合框的子项
属性。在层次结构中添加尽可能多的子项组合框
解决方案2
另一种解决方案是在视图模型中使用ILookup
,其中TKey
是ParentId
。在SelectedItem
的绑定属性中,您可以使用该项通过使用该项的父项为子组合框构建新的ItemSource