6

我有一个包含 ListBox 的 WPF 窗口。ItemsSource 绑定到视图模型的属性。

<Window x:Class="SimpleWpfApp.View.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding MainWindowViewModel, Source={StaticResource Locator}}">
  <DockPanel>
    <ListBox ItemsSource="{Binding SomeThings}" />
  </DockPanel>
</Window>

视图模型的属性是自定义接口的可观察集合;ISome 接口。该接口非常简单,由另外覆盖 ToString 的 SomeClass 实现。

public class MainWindowViewModel
{
  public ObservableCollection<ISomeInterface> SomeThings
  {
    get
    {
      var list = new List<ISomeInterface>
      {
        new SomeClass {Value = "initialised"},
        new SomeClass {Value = "in"},
        new SomeClass {Value = "code"}
      };

      return new ObservableCollection<ISomeInterface>(list);
    }
  }
}

public interface ISomeInterface
{
  string Value { get; }
}

public class SomeClass : ISomeInterface
{
  public string Value { get; set; }

  public override string ToString() => Value;
}

当我在 Visual Studio 2015 或 Blend 中查看窗口时,一切都符合预期。调用 ToString 并填充 ListBox。

混合截图

我已经创建了我想在设计模式下使用的 XAML 设计数据。我已将设计数据添加到名为 SampleData 的目录中。我在第一个 DataContext 正下方的窗口 XAML 中添加了一个设计 datacontext 语句。

d:DataContext="{d:DesignData Source=/SampleData/Data.xaml}"

这行不通。无论我将什么用于源路径,Visual Studio 和 Blend 都会报告“找不到文件或项目项”。我试过 /SampleData/Data.xaml、SampleData/Data.xaml、../SampleData/Data.xaml、./../SampleData/Data.xaml

如果我将 Data.xaml 移出 SampleData 目录并移到项目根目录中,Visual Studio 和 Blend 只会找到它。然后我可以使用源路径 /Data.xaml 或 Data.xaml 来引用它。如果我使用 Data.xaml 而不使用 / 前缀,则 Visual Studio 和 Blend 报告找不到该文件.. 但无论如何都可以找到它。

我的第一个问题是.. 我可以在子目录中使用示例数据吗?如果是这样怎么办?

在项目根目录中成功引用 Data.xaml 后,我的窗口没有调用重写的 ToString,因此我得到了显示的类名列表。该列表与设计数据具有相同数量的项目,因此看起来它正在使用设计数据。

我的第二个问题是.. 如果对象是从代码中实例化的,为什么不在这里调用被覆盖的 ToString?

我知道我可以通过指定一个项目模板来达到预期的结果。

<ListBox ItemsSource="{Binding SomeThings}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Value}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

完整的源代码可用于 github 上的示例应用程序

https://github.com/DangerousDarlow/WpfDesignData

更新

感谢 jstreet 的回答。我更改了子目录中 data.xaml 的文件属性,现在可以将其用作设计数据。我以为我以前试过这个,但我一定是弄错了。

我仍然没有看到 ToString 被调用。我尝试将视图模型属性更改为List<object>and ,List<ISomeInterface>但都导致调用 object.ToString; 由类名的显示推断。我可能会停止关注这一点,因为无论如何我都不会使用 ToString,我将绑定到我想要显示的属性。不过,最好解释一下行为上的差异。

我正在使用 Visual Studio 2015 社区版。

4

1 回答 1

5

这是一些工作示例代码。您可能想参考这篇文章 - MSDN

特别要注意如何在 VS 项目中为Data.xaml文件(在我的情况下为Dictionary1.xaml )设置属性:

在此处输入图像描述

还要注意如何创建你的根对象,SomeThings(在我的例子中是SomeClasses):

对于集合,根对象可以是 ArrayList 或派生自集合或泛型集合的自定义类型...

XAML:

<Window x:Class="WpfApplication277.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:WpfApplication277"
    d:DataContext="{d:DesignData Source=/SampleData/Dictionary1.xaml}"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListView ItemsSource="{Binding}"></ListView>
</Grid>

字典1.xaml:

右键单击SampleDataVS 项目中的文件夹,然后选择Add\New Item\WPF\Resource Dictionary,将其内容替换为您的设计数据。这应该确保您的设计数据可以位于子文件夹中。

<m:SomeClasses xmlns:m="clr-namespace:WpfApplication277">
<m:SomeClass Value="design data 1">
</m:SomeClass>
<m:SomeClass Value="design data 2">
</m:SomeClass>
<m:SomeClass Value="design data 3">
</m:SomeClass>

SomeClasses: List<SomeClass>没有工作

public class SomeClasses : List<Object>
{
    public SomeClasses() { }
}

某类:

public class SomeClass : ISomeInterface
{
    public string Value { get; set; }

    public override string ToString() => string.Format("ToString() : {0}",Value);
}

请注意,这ToString()肯定被称为:

在此处输入图像描述

于 2016-09-10T11:06:03.957 回答