没有更多背景信息,也没有关于你在做什么的细节(因为你不能发布任何代码或截图),我只能告诉你The WPF Mentality背后的基本思想是什么。
WPF 与我听说过的几乎所有其他 UI 框架都确实不同,因为它确实旨在用于以数据为中心的开发。
从头开始,WPF 主要基于DataBinding。这消除了大约 95% 的通过程序代码对 UI 进行任何操作的需要。
举个简单的例子,假设你有一个包含string LastName 和string FirstName 属性的Person 类:
public class Person
{
public string LastName {get;set;}
public string FirstName {get;set;}
}
而不是通过像这样编写过程代码隐藏来来回地将数据值传递给 UI:
//Traditional approach, Don't use this in WPF.
this.txtLastName.Text = person.LastName;
this.txtFirstName.Text = person.FirstName;
//...
person.LastName = this.txtLastName.Text;
person.FirstName = this.txtFirstName.Text;
您只需在 XAML 中以声明方式定义 DataBinding:
<TextBox Text="{Binding LastName}"/>
<TextBox Text="{Binding FirstName}"/>
然后将 UI 的 DataContext 设置为相关的数据实例:
//Window constructor example
public MainWindow()
{
InitializeComponent();
DataContext = new Person();
}
这种方法有以下优点:
- 很明显Separates UI from Data,由于这些层的独立性,允许大量的可扩展性。您可以在 UI 中添加任何内容,而无需更改应用程序逻辑/业务逻辑中的一行代码。
- 它减少了样板代码,因为 WPF 负责传递数据 In Both Directions (
Data <=> UI)。
- 它允许基于属性的方法(与基于事件的方法相反)。例如,不需要处理
TextBox.TextChanged 事件之类的事情。 WPF 负责在需要时将示例中的 TextBox 中的 Text 值传递给基础数据对象。
-
它消除了导航可视化树的需要。 WPFVisual Tree 是一个非常复杂的结构,它具有复杂的状态变化和复杂的转换以及复杂的生命周期。您真的不想想要处理这个问题,例如,“填充几个文本框”。
- 在处理 Collections 时,它有助于以自然的方式利用 WPF 的 UI Virtualization 功能(您实际上不必执行默认启用的任何操作)。这在执行时间和内存消耗方面都会导致Huge Performance Gain。
- 最后但同样重要的是,它允许使用 声明式 方法,而不是传统的 命令式 方法。您只需定义数据,然后编写业务逻辑(像往常一样以命令式形式),然后通过 DataBinding 定义 UI 及其与数据的关系。李>
这个基本概念适用于 WPF 中的 EVERYTHING。
ListBoxes、ComboBoxes、Menus、TabControls、DataGrids 和所有ItemsControls 完全相同:
您不会“使用 UserControls 填充 ListBox”,而是:
-
您创建了一个正确的ViewModel,其中包含一个包含您的数据项的IEnumerable<T>。 ObservableCollection<T> 是首选,因为 WPF 侦听它的 CollectionChanged 事件并在从集合中添加/删除项目时相应地更新 UI:
public class MyViewModel
{
public ObservableCollection<Person> People {get;set;}
//Constructor
public MyViewModel()
{
People = new ObservableCollection<Person>();
//populate the collection here...
}
}
-
然后您定义 ListBox 在 XAML 中并使用 WPF 的 Data Templating 功能定义每个项目的 UI 外观:
<ListBox ItemsSource="{Binding People}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding LastName}"/>
<TextBox Text="{Binding FirstName}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
注意:如果你想在里面使用一个 UserControl 也是一样的:
<DataTemplate>
<my:MyUserControl/>
</DataTemplate>
-
最后将 UI 的 DataContext 设置为 ViewModel 的一个实例:
//Window Constructor
public MainWindow()
{
InitializeComponent();
DataContext = new MyViewModel();
}
注意:我提到了INotifyPropertyChanged
cmets 中的接口。此接口必须由
您的数据项或视图模型以支持双向绑定
适当地。否则 WPF 无法“知道”特定属性何时
(例如LastName)已更改并相应地更新UI。一世
认为该主题超出了此答案的范围,并且
因此我不会参与其中。您可以阅读链接的材料,并且
网上也有很多关于它的资料。
正如我已经提到的,我完全没有使用 C++ 的经验,因此所有这些示例都是用 C# 编写的。
请记住,我还提到 WPF 仅支持与 .Net Objects 的数据绑定,并且我认为它不支持较低级别的内存结构,例如您可以在 C++ 中构建的结构。
我的建议是,您将 C# 用于软件的上层面向 UI 的部分,而将 C++ 用于您可能需要的任何较低层的操作。
我强烈建议阅读这篇文章中链接的材料,最重要的是 Rachel 的 WPF Mentality 和 ItemsControl 相关材料。