我在creating a menu dynamically using HierarchicalDataTemplate
的互联网上找到了一个例子。
这是xaml:
<Window x:Class="WPF_Client.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ERP_Lite" Height="350" Width="525"
WindowState="Maximized" WindowStyle="None">
<Grid>
<Grid.Resources>
<XmlDataProvider x:Key="src" XPath="/myDoc/item">
<x:XData>
<myDoc xmlns="">
<item title="One" />
<item title="Two">
<item title="First Child" />
<item title="Second Child" />
<item title="Third Child" />
<item title="Fourth Child">
<item title="First Grand Child" />
<item title="Second Grand Child" />
<item title="Third Grand Child" />
</item>
</item>
<item title="Three" />
<item title="More" />
</myDoc>
</x:XData>
</XmlDataProvider>
</Grid.Resources>
<Menu DataContext="{StaticResource src}" ItemsSource="{Binding}">
<Menu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding XPath=item}">
<TextBlock Text="{Binding XPath=@title}" />
</HierarchicalDataTemplate>
</Menu.ItemTemplate>
</Menu>
</Grid>
</Window>
上面的xaml运行得非常好。现在我想使用SQL Server而不是xml数据源创建相同的东西。
所以,为此我创建了一个表并添加了如下数据:
ID | Title | ParentID
----+------------------------+-----------
1 | One | NULL
2 | Two | NULL
3 | Three | NULL
4 | Four | NULL
5 | First Child | 2
6 | Second Child | 2
7 | Third Child | 2
8 | Fourth Child | 2
9 | First Grand Child | 8
10 | Second Grand Child | 8
11 | Third Grand Child | 8
现在有人可以告诉我如何用菜单绑定这个表的数据吗?
注意:我正在使用EntityFramework和MVVM。
更新
对不起,我在这个例子中没有使用过您的代码,因为我不理解Model
,the constructor of Node
之类的内容,也没有填写父或子的值属性,所以它是我的界限,我尝试使用一种不同于你的方法。虽然你已经使用了参数化的构造函数,但是你从不向构造函数提供值,所以我觉得很难。
以下是我的尝试:
这是我的MenuItem模型类:
public partial class MenuItem
{
public MenuItem()
{
this.MenuItems1 = new HashSet<MenuItem>();
}
public int MenuItemID { get; set; }
public string Title { get; set; }
public Nullable<int> ParentID { get; set; }
public virtual ICollection<MenuItem> MenuItems1 { get; set; }
public virtual MenuItem MenuItem1 { get; set; }
}
这是我为MenuItem类创建的数据传输对象,用于解决循环引用错误:
public class MenuItemDTO
{
public int MenuItemID { get; set; }
public string Title { get; set; }
public Nullable<int> ParentID { get; set; }
}
以下是我在WCF服务中使用的方法:
public IEnumerable<MenuItemDTO> GetAllMenuItems()
{
using (Entities db = new Entities())
{
return (from m in db.MenuItems
select new MenuItemDTO
{
MenuItemID = m.MenuItemID,
Title = m.Title,
ParentID = m.ParentID
}).ToList();
}
}
这是我的MainWindowViewModel:
public class MainWindowViewModel : MainViewModel
{
public MainWindowViewModel()
{
ERP_Lite_ServiceClient client = new ERP_Lite_ServiceClient();
Parents = new ObservableCollection<MenuItemDTO>
(client.GetAllMenuItems().Where(m => m.ParentID == null));
Children = new ObservableCollection<MenuItemDTO>
(client.GetAllMenuItems().Where(m => m.ParentID != null));
client.Close();
}
private ObservableCollection<MenuItemDTO> _parents;
public ObservableCollection<MenuItemDTO> Parents
{
get
{
return _parents;
}
set
{
_parents = value;
OnPropertyChanged("Parents");
}
}
private ObservableCollection<MenuItemDTO> _children;
public ObservableCollection<MenuItemDTO> Children
{
get
{
return _children;
}
set
{
_children = value;
OnPropertyChanged("Children");
}
}
}
这是xaml:
<Menu ItemsSource="{Binding Parents}">
<Menu.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type Service:MenuItemDTO}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Title}" />
</HierarchicalDataTemplate>
</Menu.ItemTemplate>
</Menu>
但是我的代码遇到了一些问题。在输出中,我获得所有父项,但不显示子项。你能救我吗?
答案 0 :(得分:2)
为了与HierarchicalDataTemplate
合作,您的 ViewModel 也需要具有层次结构。这意味着ItemsSource
内的HierarchicalDataTemplate
与该节点相关。但是在你的代码中你已经在同一个 ViewModel 中定义了 Parent 和 Children ,
将MenuItemDTO
视为树中的一个随机节点,因此它应该有一些具有相同类型(MenuItemDTO
)的子节点。
如果您将ItemsSource
Menu
设置为"{Binding Parents}"
,则表示该菜单的顶级项目为“父母”。
现在,如果您将ItemsSource
的{{1}}设置为HierarchicalDataTemplate
,则可以通过查看自己的"{Binding Children}"
找到该节点的子节点。应该为树中的每个节点设置。
将ItemsSource
移至Children
。
然后您可能需要稍微修改MenuItemDTO
。
尝试下面的代码(经过测试,工作正常)。它返回属于第一级菜单的GetAllMenuItems()
列表,每个菜单都递归填充MenuItemDTO
。
第一级树(菜单)=没有父级的菜单项
Children