我有一个包含项目数组的视图模型:
public class FooViewModel
{
public FooListItem[] ListItems { get; set; }
...
}
我创建了一个子类,用作带有虚拟数据的设计时模拟。
public class FooViewModelMock : FooViewModel
{
public FooViewModelMock()
{
ListItems = <test data population...>
...
}
}
然后,我将模拟数据连接到窗口中,效果很好。
<Window xmlns:mocks="clr-namespace:FooNS.Mocks"
xmlns:models="clr-namespace:FooNS.Model"
d:DataContext="{d:DesignInstance Type=mocks:FooViewModelMock, IsDesignTimeCreatable=True}"> ...
然后在窗口中,我有一个DataGrid并将ItemsSource绑定到视图模型上的属性:
<DataGrid ItemsSource="{Binding ListItems}"> ...
测试数据可以在设计窗口中很好地显示,但问题在于DataGrid的数据上下文仍然是FooViewModelMock,而不是FooListItem,因此我失去了智能感知能力,并收到诸如“无法解析类型为'FooViewModelMock'的数据上下文中的'xxx'之类的消息'”。
我当然可以在DataGrid中设置数据上下文:
d:DataContext="{d:DesignInstance models:FooListItem}"
这使我的智能感知恢复了,但是我丢失了模拟数据。
有没有办法让我在设计时数据上下文中通过ItemsSource绑定向下传播,并同时保留智能感知和设计视图数据?
谢谢
据我所知,这是Visual Studio中的一个缺陷。这是我的解决方法。
首先,我不使用DesignInstance,因为我无法使它在Visual Studio 2013中正常工作。相反,我使用以下代码:
d:DataContext="{x:Static userControls:[ insert class name here ]DesignerData.Example}"
示例是创建... DesignerData类的实例的静态属性。我不知道为什么会这样,但是应该完全一样的DesignInstance却不行。我试图指定IsDesignTimeCreatable,但这没有帮助。
此类必须具有必需的collection属性,在我的情况下,该属性仅返回匿名类型对象形式的数据:
public IEnumerable<object> Elements
{
get
{
return new object[]
{
new { ... },
new { ... },
new { ... }
};
}
}
以我为例,通常在不运行应用程序其余部分的情况下通常无法轻松创建Elements,因此使用这种匿名类型的对象可以避免Elements中的大量代码,从而使它们在设计时的行为有所不同。
由于Visual Studio中的缺陷,我们还必须具有元素的属性:
public string Key { get; private set; }
public Element Value { get; private set; }
但是请注意,这只是为了避免警告和自动完成。这些将永远不会被实际读取。
这种方法的一个很大的潜在缺点是,如果一个集合中的元素具有与另一个集合中的元素相同名称但类型不同的属性,则无法使用该方法。
这也是笨拙和不便的,因为不会有变通办法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句