我有一个包含ListBox的WPF窗口。ItemsSource绑定到视图模型的属性。
视图模型的属性是一个自定义接口 ISomeInterface 的可观察集合。该接口非常简单,由 SomeClass 实现,它还覆盖了 ToString 方法。
当我在Visual Studio 2015或Blend中查看窗口时,一切都符合预期。ToString被调用并填充ListBox。 Blend截图 我已经创建了XAML设计数据,希望在设计模式下使用它。我将设计数据添加到名为SampleData的目录中。我在第一个DataContext下方立即添加了一个设计数据上下文语句。
这不起作用。无论我使用什么源路径,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,而如果对象是从代码实例化的,则会调用?
我知道可以通过指定项模板来实现所需的结果。
<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>
视图模型的属性是一个自定义接口 ISomeInterface 的可观察集合。该接口非常简单,由 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;
}
当我在Visual Studio 2015或Blend中查看窗口时,一切都符合预期。ToString被调用并填充ListBox。 Blend截图 我已经创建了XAML设计数据,希望在设计模式下使用它。我将设计数据添加到名为SampleData的目录中。我在第一个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>
和List<ISomeInterface>
,但都会导致调用object.ToString;通过显示类名来推断。我可能会停止寻找,因为我不会使用ToString,我将绑定要显示的属性。不过解释一下行为上的区别还是很好的。
我正在使用Visual Studio 2015社区版。