1

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

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

我没有足够的声誉点来发布图片,所以我发布了图片,所以我使用了一个示例/测试域。您可以在此处查看 WPF 应用程序和代码的屏幕截图:

http://digitalworkzone.com/WPF.html

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

4

2 回答 2

2

了解 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并因此将处理其自己的呈现。

在上面的图片示例中,您有要填写图形信息的ListBoxes/ 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' 都派生自 ' )。DataTypePerson

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

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/ 。

于 2013-07-19T20:13:45.937 回答
1
<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}}"

于 2013-07-19T20:20:50.503 回答