【发布时间】:2019-01-30 06:06:10
【问题描述】:
我是 WPF 新手。我正在将一个 Win Forms 应用程序迁移到 WPF,这需要我大量学习。
在 WinForms 中,我会创建一个公共控件的子类(MyLabel:Label、MyDataGrid:DataGrid 等) 这将允许我设置所有我需要的属性和样式,并且这些对于我随后使用的任何控件都是一致的。此外,我可以在这些控件上实现可用于我的所有控件的功能。
我在 WPF 中使用 TreeView/TreeViewItem 做到这一点非常失败。 我用普通的 TreeView 创建了一个工作示例,然后在 MainPage 中简单地替换了 MyTreeView。我得到: System.InvalidOperationException: 'Items 集合在使用 ItemsSource 之前必须为空。'
希望您可以从此链接下载项目: https://app.box.com/s/9ofyuwfgk2cobqhokezgkknvtnmzmeq7
部分设计更改是将菜单实现为屏幕左侧的树形视图。这将有大约 60 个选项。
我花了一些时间,并有一个填充的 TreeView。 但是,我相信可以在这里使用菜单,并将其设置为树视图。这个对吗? 如果是这样,谁能给我举个例子,因为我在谷歌上找不到。 Google 似乎认为我想要 TreeView 上的上下文菜单。
编辑添加代码:
TreeView xaml(TreeViewItem 基本相同)
<TreeView x:Class="WpfApp1.Controls.MyTreeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
</Grid>
</TreeView>
树视图cs
using System.Windows;
using System.Windows.Controls;
namespace WpfApp1.Controls
{
/// <summary>
/// Interaction logic for MyTreeView.xaml
/// </summary>
public partial class MyTreeView : TreeView
{
public MyTreeView()
{
InitializeComponent();
}
protected override DependencyObject GetContainerForItemOverride()
{
return new MyTreeView();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is MyTreeView;
}
}
主窗口
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:Controls="clr-namespace:WpfApp1.Controls"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<XmlDataProvider x:Key="treeViewStructure" Source="Data/treeViewStructure.xml" XPath="./*/Category"/>
<HierarchicalDataTemplate DataType="Category" ItemsSource="{Binding XPath=*}">
<TextBlock Text="{Binding XPath=@Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="SubCategory" ItemsSource="{Binding XPath=*}">
<TextBlock Text="{Binding XPath=@Name}"/>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<Controls:MyTreeView x:Name="mainTreeViewMenu"
Grid.Column="0"
BorderThickness="0"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource treeViewStructure}}" DataContext="{DynamicResource treeViewStructure}"/>
</Grid>
</Window>
将 Controls:MyTreeView 更改为简单的 TreeView 将使应用程序能够正常运行
ETA2:布拉德利的 XML:
<?xml version="1.0" encoding="utf-8" ?>
<Categories>
<Category Name="1">
<SubCategory Name="A"/>
<SubCategory Name="B"/>
</Category>
<Category Name="2">
<SubCategory Name="C"/>
<SubCategory Name="D"/>
<SubCategory Name="E"/>
<SubCategory Name="F"/>
<SubCategory Name="G"/>
<SubCategory Name="H"/>
</Category>
<Category Name="3">
<SubCategory Name="I"/>
<SubCategory Name="J"/>
</Category>
<Category Name="4">
<SubCategory Name="K"/>
<SubCategory Name="L"/>
</Category>
</Categories>
【问题讨论】:
-
这是因为“menu”类通常用于上下文菜单。您不会使用一个来替换树视图。另外,请在此处发布相关代码。我们无法为您提供帮助
-
感谢您的回复。我在这里找到了一篇文章(现在找不到),建议将菜单样式设置为树视图,而不是尝试将树视图用作菜单。现在直接添加代码。
-
像这样在树视图上设置数据上下文是非常奇怪的。我会尝试删除它。除此之外,我没有看到您的异常的明显来源。
-
您正在添加一个
<Grid>作为 TreeView 的子控件,并且添加一个空控件。这就是你的异常的根源,你想达到什么目的? -
还请记住,WPF 是专门设计的,因此很少需要子类化 Windows 控件。 Matthew McDonalds 的优秀著作《Pro WPF in C#》中有这样一段话:“在以前的 Windows 开发框架中,自定义控件发挥了核心作用。但是在 WPF 中,重点已经转移。自定义控件仍然是构建自定义小部件的有用方法,您可以在应用程序之间共享,但当您想要增强和自定义核心控件时,它们不再是必需的.....