在WPF数据库驱动的应用程序结果中使用图标



我正在尝试制作一个WPF应用程序。应用程序需要使用"列表视图"来显示对数据库的查询结果。我已经能够成功地创建应用程序(GUI、数据库、LINQ等),但是,我的查询结果的显示看起来更像"网格"。

下面项目的规范显示,结果中出现的每个记录旁边都需要有一个绿色圆圈图标。我已经从下面的图像中删除了实际结果,以保持数据库的内容私有。

我没有足够的信誉点来发布图片,所以我发布了图片作为我使用的示例/测试域。你可以在这里看到WPF应用程序的屏幕截图和代码:

http://digitalworkzone.com/WPF.html

我做错了什么?我是否需要在代码中添加或修改一些内容,以便能够获得绿色圆圈和更多的"列表"样式来显示我的查询结果?

了解WPF内容模型。http://msdn.microsoft.com/en-us/library/bb613548.aspx

任何具有"Content"属性的东西基本上都有两种行为。如果"Content"设置为从UIElement派生的内容,则该类将管理自己的表示。然而,其他任何东西都只会调用.ToString(),而是显示文本。

从长远来看,这意味着WPF中的所有内容都可以显示任何内容。如果你想在按钮中显示一个按钮,你可以。例如:

<Button>
    <Button.Content>
        <Button Content="This will show as text" />
    </Button.Content>
</Button>

内部按钮将有文本,但外部按钮将显示Button,因为Button源自UIElement,因此将处理自己的演示。

在上面的图片示例中,您有想要用图形信息填充的ListBoxes/DataGrids。试试这个:

<ListBox HorizontalContentAlignment="Stretch">
    <ListBox.Items>
        <Button Content="One"/>
        <Button Content="Two"/>
        <Button Content="Three"/>
        <Button Content="Four"/>
    </ListBox.Items>
</ListBox>

现在您有一个ListBox,它显示Buttons而不是Text。您可以更进一步,将项目包含在堆叠面板中,例如:

<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,则实际上可以使用DataTemplate来显示内容。DataTemplate实际上是以一个特定类为目标,并按照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对它们进行布局。如果您使用多态性(例如在不同类型的人中,如"Cusomters"或"Employees",它们都源自"Person"),则可以通过使用DataType属性来获得DataTemplate目标特定类。

这种方法的问题是直接设置项的值,这是不好的形式。最好定义一个单独处理视图所有数据的类。考虑:

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中名为"People"的任何公共属性,然后检索这些结果。"。这基本上是MVVM方法背后的基础。您可能将所有业务逻辑都放在一个或多个类中,这些类处理Model中的主应用程序操作,但您也有一个ViewModel,它与Model交互并将结果公开为公共属性。WPF会自动绑定到这些属性,并将它们呈现给您。信息只是流动,而不是强行设置值。

要真正理解WPF应该如何工作,您应该花一些时间来理解MVVM的基础知识。WPF的设计确实考虑到了MVVM,所以要真正了解WPF的工作原理,你真的应该花点时间来了解它http://agilewarrior.wordpress.com/2011/01/11/simple-mvvm-walkthrough-part-i/。

<ListBox ItemsSource="{Binding QueryResults}">
  <ListBox.ItemsTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <Image Source="{Binding ImageSource}"/>
        <TextBlock Text="{Binding TextSource}"/>
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemsTemplate>
</ListBox>

如果您的代码后面有一个名为QueryResults的对象列表,则会起作用。每个对象都需要具有名为ImageSource的字符串属性和名为TextSource的字符串属性。

但是,由于只需要为每个项目显示一个绿色圆圈图标,因此可以对图像源进行硬编码。不过,如果你想为每一个都有一个不同的图标,上面的内容就会起作用。

还要注意,为了使其工作,您需要将窗口的DataContext设置为DataContext="{Binding RelativeSource={RelativeSource Self}}"

最新更新