与 CollectionViewSource 绑定时,DesignTime 数据未显示在 Blend 中
Posted
技术标签:
【中文标题】与 CollectionViewSource 绑定时,DesignTime 数据未显示在 Blend 中【英文标题】:DesignTime data not showing in Blend when bound against CollectionViewSource 【发布时间】:2009-09-19 06:35:33 【问题描述】:我有一个视图模型的数据模板,其中项目控件绑定到 CollectionViewSource(以启用 xaml 中的排序)。
<DataTemplate x:Key="equipmentDataTemplate">
<Viewbox>
<Viewbox.Resources>
<CollectionViewSource x:Key="viewSource" Source="Binding Modules">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="ID" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Viewbox.Resources>
<ItemsControl ItemsSource="Binding Source=StaticResource viewSource"
Height="DynamicResource equipmentHeight"
ItemTemplate="StaticResource moduleDataTemplate">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Viewbox>
</DataTemplate>
我还设置了 UserControl,所有这些都被定义为提供设计时数据
d:DataContext="x:Static vm:DesignTimeHelper.Equipment">
这基本上是一个静态属性,它为我提供了一个具有 ModuleViewModel (Equipment.Modules) 列表的 EquipmentViewModel。现在只要我绑定到 CollectionViewSource,设计时数据就不会显示在混合 3 中。当我直接绑定到 ViewModel 集合时
<ItemsControl ItemsSource="Binding Modules"
我可以看到设计时数据。知道我能做什么吗?
【问题讨论】:
有同样的问题。绑定 List做过(至少现在):)
这是我找到的解决方案。诀窍是覆盖 CollectionViewSource 设计时的源。我使用d:DesignSource
属性来使用另一个静态资源设计时间:
<Window.Resources>
<CollectionViewSource x:Key="ViewSource"
Source="Binding ModelProperty"
d:DesignSource="x:Static MyProg:DesignTimeData.MyList">
<!-- Contents -->
</CollectionViewSource>
</Window.Resources>
<!-- No change to the using class -->
<ListBox ItemsSource="Binding Source=StaticResource ViewSource">
</ListBox>
【讨论】:
【参考方案2】:-
我不确定
x:Static
是否应该在 d:DataContext
中工作,我认为只有 d:DesignInstance 或 d:DesignData
可以。
您是否测试了设计时数据并确定确实填充了数据?
尝试在d:DesignInstance
中指定d:IsDesignTimeCreatable=True
属性。
虽然 this 是 Silverlight 特有的,但我相信它可能会给您一些提示。
它通常应该是这样的:
d:DataContext="d:DesignInstance Type=vm:EquipmentViewModel,
IsDesignTimeCreatable=True"
您可以在运行时和设计时使用相同的 ViewModel,在您的 ViewModelBase
中创建一个 IsInDesignTime
属性并适当地返回数据。
示例:
private static bool? _isInDesignMode;
public static bool IsInDesignModeStatic
get
if (!_isInDesignMode.HasValue)
var prop = DesignerProperties.IsInDesignModeProperty;
_isInDesignMode
= (bool)DependencyPropertyDescriptor
.FromProperty(prop, typeof(FrameworkElement))
.Metadata.DefaultValue;
return _isInDesignMode.Value;
注意:我鼓励您使用StaticResources
(而不是DynamicResources
)用于在运行时不会更改的模板或样式。阅读this了解更多信息。
【讨论】:
【参考方案3】:不确定这是否仍然相关...最近有一个类似的问题 - 我仍处于 WPF 学习曲线的某个位置,只是不太确定在哪里...
无论如何,这里是这样的场景:例如,我会在我的本地命名空间中的某处创建一个 ObservableCollection 类型的对象(为了简单起见)。
public class NodesCollection : ObservableCollection<Nodes>
然后从 Blend/Xaml 中,我可以轻松地“创建对象数据源”(从数据工具面板)并找到 NodesCollection
已显示并且可以选择。
接下来,Blend 将在 Xaml 文件顶部附近创建一个本地资源,类似于:
<local:NodesCollection x:Key="NodesCollectionDataSource" d:IsDataSource="True" />
这样,您可以轻松地将列表框的ItemsSource
属性绑定到我们刚刚创建的数据源。例如,在“对象和时间线”工具面板中右键单击列表框,选择“数据将ItemsSource绑定到数据..”在弹出的对话框中,您会很容易看到NodesCollectionDataSource
可用并且可以使用。
然而,我必须解决的问题来了……
在我目前正在阅读的一些书籍中,他们谈到在 Xaml 中创建一个 CollectionViewSource 可用于对其基础数据源进行排序/分组/过滤/导航。
第一个问题,我在 Blend 的任何地方都找不到 CollectionViewSource;所以唯一的选择是在 Xaml 中手动创建标签。
只需在资源块 (Xaml) 中键入 <CollectionViewSource x:Key="cvsNodes" />
,然后您就可以使用 Blend GUI 修改其他属性;例如设置基础 Source 属性和附加的 Sort 和 Group Descriptors(位于 Resources 工具面板下)。
现在是我们想要将 ListBox 的 ItemsSource 属性绑定到 CollectionViewSource 的部分。但是,您将无法使用 Blend GUI 找到该项目。因此,您必须手动键入绑定值。例如:
<ListBox x:Name=.. ItemsSource="Binding Source=DynamicResource cvsNodes".. />
这行得通。但为了更简单,我们需要回到 Xaml 中的原始 CollectionViewSource 资源元素并添加一个附加属性:
<CollectionViewSource x:Key="cvsNodes" Source=... d:IsDataSource="True"
d:IsDataSource="True"
可以让 Blend GUI 将资源识别为可用资源。
现在,如果我们从“属性”工具面板返回到 ListBox 的 ItemsSource 属性,我们应该能够从可用数据源列表中选择 cvsNodes
。
我希望这对可能得出与我相同结论的任何人有所帮助,即 Blend 和底层 Xaml 技术并未完全同步;而且 Blend 充其量只是生成 Xaml 的工具,而不是学习 Xaml 语言的替代品。
【讨论】:
也只是为了帮助回答原始问题;是的,这确实允许 Blend 在开发过程中显示示例数据。您需要做的就是在 ObjectCollection 类的构造函数中填充一些示例数据 - 在我的情况下,这将是 NodesCollection 的 ctor以上是关于与 CollectionViewSource 绑定时,DesignTime 数据未显示在 Blend 中的主要内容,如果未能解决你的问题,请参考以下文章
CollectionViewSource,如何过滤数据?