gpt4 book ai didi

c# - 使用 sql server 在 wpf 中动态创建菜单

转载 作者:行者123 更新时间:2023-12-03 10:28:29 25 4
gpt4 key购买 nike

我在互联网某处找到了 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

现在谁能告诉我如何将此表的数据与菜单绑定(bind)?

注意:我使用的是 EntityFramework 和 MVVM。

更新

对不起,我没有在这个例子中使用你的代码,因为我不明白什么是 Model , the constructor of Node而且您没有填写 Parent 或 Children 属性中的值,所以这一切都超出了我的范围,我尝试使用与您有所不同的方法。尽管您使用了参数化构造函数,但您从未向构造函数提供值,所以我真的觉得很难。

这是我尝试过的:

这是我的 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>

但是我的代码有一些问题。在输出中,我得到了所有父项,但没有显示子项。你能帮助我吗?

最佳答案

为了与 HierarchicalDataTemplate 合作您的 ViewModel 也需要分层。这意味着 ItemsSource里面 HierarchicalDataTemplate是相对于那个节点的。但是在您的代码中,您在同一个 ViewModel 中定义了 Parent 和 Children,

想想MenuItemDTO作为树中的一个随机节点,因此它应该有一些具有相同类型的子节点( MenuItemDTO )。

如果您设置 ItemsSourceMenu"{Binding Parents}"这意味着菜单的顶级项目是 parent 。

现在,如果您设置 ItemsSourceHierarchicalDataTemplate"{Binding Children}" ,它可以通过查看自己的 ItemsSource 来找到该节点的子节点.应该为树中的每个节点设置。

解决方案:

移动ChildrenMenuItemDTO .

那么您可能需要修改 GetAllMenuItems()一点。

试试下面的代码(它已经过测试并且工作正常)。它返回 MenuItemDTO 的列表s 属于一级菜单,每个都有它的Children递归填充。

树的第一级(菜单)= 没有父级的菜单项

public IEnumerable<MenuItemDTO> GetAllMenuItems()
{
using (Entities db = new Entities())
{
//get all items and put them in a simple list
var allItems = (from m in db.MenuItems
select new MenuItemDTO
{
MenuItemID = m.MenuItemID,
Title = m.Title,
ParentID = m.ParentID
}).ToList();

//define another list and put "only" root items in it
// this will have a hierarchical structure (By correcting the Children)
// and it's the output of this function
var roots = allItems.Where(x => x.ParentID == null);

//here we correct Children of each item
//since both allItems and roots share the same elements (call-by-reference)
//instead of searching through a tree, simply search through allItems
foreach (var item in allItems)
{
//find the correct parent for current item
var parent = allItems.FirstOrDefault(x => x.MenuItemID == item.ParentID);

//add the item to Children of its parent
// by doing this, one single item in both allItems
// and roots (or recursively in roots) will be corrected
if(parent!=null)
parent.Children.Add(item);

//if you don't want to miss any menu item:
//else roots.Add(item);
}
return roots;
}
}

关于c# - 使用 sql server 在 wpf 中动态创建菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22118003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com