了解 WPF 内容模型。http://msdn.microsoft.com/en-us/library/bb613548.aspx
任何具有“内容”属性的东西基本上都以两种方式表现。如果“内容”设置为派生自 的内容UIElement
,则该类将管理它自己的演示文稿。但是,其他任何东西都会被.ToString()
调用,而是显示文本。
从长远来看,这意味着 WPF 中的所有内容都可以显示任何内容。如果你想在一个按钮中显示一个按钮,你可以。例如:
<Button>
<Button.Content>
<Button Content="This will show as text" />
</Button.Content>
</Button>
内部按钮将具有文本,但外部按钮将显示 aButton
因为Button
派生自UIElement
并因此将处理其自己的呈现。
在上面的图片示例中,您有要填写图形信息的ListBox
es/ s。DataGrid
试试这个:
<ListBox HorizontalContentAlignment="Stretch">
<ListBox.Items>
<Button Content="One"/>
<Button Content="Two"/>
<Button Content="Three"/>
<Button Content="Four"/>
</ListBox.Items>
</ListBox>
现在您有一个显示Buttons
而不是文本的 ListBox。您可以更进一步,将项目包含在堆栈面板中,例如:
<ListBox HorizontalContentAlignment="Stretch">
<ListBox.Items>
<StackPanel Orientation="Horizontal">
<Button Content="A button"/>
<Label Content="Some text" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="A button"/>
<Label Content="Some text" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="A button"/>
<Label Content="Some text" />
</StackPanel>
</ListBox.Items>
</ListBox>
现在我们有了包含布局容器(StackPanels
然后包含其他元素)的项目。
但是,如果你在ItemsSource
别处设置,你实际上可以使用 aDataTemplate
来显示内容。ADataTemplate
实际上以特定类为目标,并按照 XAML 中的定义布置其内容。考虑:
代码背后:
public partial class MyWindow : UserControl {
public MyWindow() {
InitializeComponent();
MyListBox.ItemsSource = new List<Person> {
new Person("Sam", "Smith"),
new Person("Jim", "Henson"),
new Person("Betty", "White"),
};
}
XAML:
<ListBox HorizontalContentAlignment="Stretch" x:Name="MyListBox" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Label Content="{Binding FirstName}"/>
<Label Content="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
现在,当 Listbox 显示时,它将循环显示ItemsSource
属性中的每个项目,然后使用 DataTemplate 对它们进行布局。如果您使用多态性,则可以通过使用该属性来获得DataTemplate
目标特定类(如在不同类型的人中,例如 'Cusomters' 或 'Employees' 都派生自 ' )。DataType
Person
这种方法的问题是您直接设置项目的值,这是不好的形式。最好定义一个类来分别处理视图的所有数据。考虑:
public class ViewModel {
// WPF will automatically read these properties using reflection.
public List<Person> People {
get {
return new List<Person> {
new Person("Sam", "Smith"),
new Person("Jim", "Henson"),
new Person("Betty", "White")
};
}
}
}
这将保存视图的所有数据,现在让我们将其添加到实际窗口中。首先我们需要引用命名空间('xmlns' 表示 xml 命名空间):
<Window x:Class="Sharp.MyWindow"
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:lol="clr-namespace:Sharp">
命名空间是Sharp
(我的东西所在的命名空间),我们给它起的别名是lol
. 现在我们ViewModel
通过将其设置为属性来将我们的类附加到窗口DataContext
,如下所示:
<Window>
<Window.DataContext>
<lol:ViewModel />
</Window.DataContext>
</Window>
这使得类上的所有公共属性ViewModel
都可用于Window
. 这样,如果我们想将Persons
信息读入我们的ListBox
,我们只需说:
<ListBox HorizontalContentAlignment="Stretch" ItemsSource="{Binding People}" >
...
</ListBox>
请注意,我们说ItemsSource={Binding People}
,这意味着“扫描ViewModel
任何名为“人物”的公共属性,然后检索这些结果。这本质上是 MVVM 方法背后的基础。您可能将所有业务逻辑放在一个或多个处理 a 中的主要应用程序操作的类中Model
,但随后您有一个ViewModel
与 交互Model
并将结果公开为公共属性的类。WPF 会自动绑定到这些属性并为您呈现它们。信息只是流动,而不是强制设定值。
要真正了解 WPF 应该如何工作,您应该花一些时间来了解 MVVM 的基础知识。WPF 的设计确实考虑到了 MVVM,因此要真正了解 WPF 应该如何工作,您真的应该花时间了解它。看看:
http ://agilewarrior.wordpress.com/2011/01/11/simple-mvvm-walkthrough-part-i/ 。