简体   繁体   English

绑定到WPF中的设计数据

[英]Binding to design data in WPF

I have a WPF window containing a ListBox. 我有一个包含ListBox的WPF窗口。 The ItemsSource is bound to a property of a view model. 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>

The property of the view model is an observable collection of a custom interface; 视图模型的属性是自定义接口的可观察集合; ISomeInterface. ISomeInterface。 The interface is very simple and is implemented by SomeClass which additionally overrides ToString. 界面非常简单,由SomeClass实现,它还会覆盖ToString。

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;
}

When I view the window in Visual Studio 2015 or Blend all is as expected. 当我在Visual Studio 2015或Blend中查看窗口时,所有内容都符合预期。 ToString is called and the ListBox populated. 调用ToString并填充ListBox。

Blend screenshot 混合截图

I have created XAML design data which I want to use when in design mode. 我创建了XAML设计数据,我想在设计模式下使用它。 I have added the design data in a directory called SampleData. 我已将设计数据添加到名为SampleData的目录中。 I add a design datacontext statement to the window XAML immediately below the first DataContext. 我将设计datacontext语句添加到第一个DataContext正下方的窗口XAML中。

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

This doesn't work. 这不起作用。 Visual Studio and Blend report 'File or project item not found' regardless of what I use for source path. 无论我使用什么来源路径,Visual Studio和Blend报告'找不到文件或项目项'。 I have tried /SampleData/Data.xaml, SampleData/Data.xaml, ../SampleData/Data.xaml, ./../SampleData/Data.xaml 我试过/SampleData/Data.xaml,SampleData / Data.xaml,.. / SampleData / Data.xaml,。/。/ SampleData / Data.xaml

Visual Studio and Blend only find Data.xaml if I move it out of the SampleData directory and into the project root. 如果我将Data.xaml移出SampleData目录并进入项目根目录,Visual Studio和Blend只能找到Data.xaml。 Then I am able to reference it using source path /Data.xaml or Data.xaml. 然后我可以使用源路径/Data.xaml或Data.xaml来引用它。 If I use Data.xaml without prefixing / then Visual Studio and Blend report that the file cannot be found.. but find it anyway. 如果我使用Data.xaml而没有前缀/然后Visual Studio和Blend报告无法找到该文件..但无论如何都要找到它。

My first question is .. Can I use sample data in a sub-directory? 我的第一个问题是..我可以在子目录中使用样本数据吗? And if so how? 如果是这样怎么样?

Having successfully referenced Data.xaml in the project root, my window is not calling the overridden ToString so I'm getting a list of class name displayed. 在项目根目录中成功引用了Data.xaml之后,我的窗口没有调用重写的ToString,因此我得到了一个显示类名列表。 The list has the same number of items as the design data so it appears it is using the design data. 该列表与设计数据具有相同数量的项目,因此它看起来正在使用设计数据。

My second question is .. Why is the overridden ToString not being called here when it is if the objects are instantiated from code? 我的第二个问题是..为什么在从代码中实例化对象时,是否在这里调用被覆盖的ToString?

I'm aware I can achieve the desired result by specifying an item template. 我知道我可以通过指定项目模板来实现所需的结果。

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

Full source is available for the example application on github 完整源代码可用于github上的示例应用程序

https://github.com/DangerousDarlow/WpfDesignData https://github.com/DangerousDarlow/WpfDesignData

UPDATE UPDATE

Thanks to jstreet for answering. 感谢jstreet的回答。 I changed the file properties for data.xaml in the sub directory and am now able to use this as design data. 我在子目录中更改了data.xaml的文件属性,现在我可以将其用作设计数据。 I thought I'd tried this before but I must be mistaken. 我以为我以前试过这个,但我一定是弄错了。

I'm still not seeing ToString being called. 我还没有看到ToString被调用。 I tried changing the view model property to List<object> and also List<ISomeInterface> but both resulted in called to object.ToString; 我尝试将视图模型属性更改为List<object>以及List<ISomeInterface>但两者都导致调用object.ToString; deduced by the display of the class name. 通过显示类名推断出来。 I'll probably stop looking at this point as I'm not going to be using ToString anyway, I'll bind to the properties I want to display. 我可能会停止看这一点,因为我不打算使用ToString,我将绑定到我想要显示的属性。 It would be good to explain the difference in behaviour though. 尽管如此,解释行为上的差异会更好。

I'm using Visual Studio 2015 community edition. 我正在使用Visual Studio 2015社区版。

Here's some working sample code. 这是一些工作示例代码。 You may want to refer to This article - MSDN . 您可能需要参考本文 - MSDN

In particular, note how to set properties for your Data.xaml file ( Dictionary1.xaml , in my case) in your VS project: 特别要注意如何在VS项目中设置Data.xaml文件的属性(在我的例子中是Dictionary1.xaml ):

在此输入图像描述

Also note how to create your root object, SomeThings ( SomeClasses in my case): 还要注意如何创建根对象SomeThings (在我的例子中是SomeClasses ):

For collections, the root object can be an ArrayList or a custom type that derives from a collection or generic collection... 对于集合,根对象可以是ArrayList或从集合或泛型集合派生的自定义类型......

XAML: 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>

Dictionary1.xaml: Dictionary1.xaml:

Right-click SampleData folder in your VS project, and select Add\\New Item\\WPF\\Resource Dictionary , replace its contents with your design data. 右键单击VS项目中的SampleData文件夹,选择Add \\ New Item \\ WPF \\ Resource Dictionary ,将其内容替换为您的设计数据。 This should make sure your design data can be located in a sub-folder. 这应该确保您的设计数据可以位于子文件夹中。

<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> did NOT work ! 几类: List<SomeClass> 没有工作!

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

SomeClass: SomeClass的:

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

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

Note that ToString() is definitely being called: 请注意, ToString()肯定被调用:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM