我有一个viewmodel的datatemplate,其中itemscontrol绑定到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}"
我可以看到设计时数据。知道我能做什么吗?
答案 0 :(得分:7)
做到了(现在至少):)
这是我找到的解决方案。诀窍是覆盖CollectionViewSource设计时的源。我使用d:DesignSource
属性来使用另一个静态资源设计时:
<Window.Resource>
<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>
答案 1 :(得分:0)
x:Static
应该在d:DataContext
中工作,我认为只有d:DesignInstance或d:DesignData
可以。d:IsDesignTimeCreatable=True
。d:DesignInstance
属性
通常应该是这样的:
d:DataContext="{d:DesignInstance Type=vm:EquipmentViewModel,
IsDesignTimeCreatable=True}"
您可以在运行时和设计时使用相同的ViewModel,在IsInDesignTime
中创建ViewModelBase
属性并适当地返回数据。
例如:
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了解详情。
答案 2 :(得分:0)
不确定这是否仍然相关......最近有一个类似的问题 - 我仍然在 WPF学习曲线的某个地方,只是不太确定在哪里......
无论如何,这是场景:我会在我的本地命名空间中创建一个ObservableCollection类型的对象(为了简单起见),例如..
public class NodesCollection : ObservableCollection<Nodes> { }
然后从Blend / Xaml,我可以轻松地“创建对象数据源”(来自数据工具面板)并显示NodesCollection
,并且可以选择。
接下来,Blend将在Xaml文件顶部附近创建一个本地资源,类似于:
<local:NodesCollection x:Key="NodesCollectionDataSource" d:IsDataSource="True" />
通过这种方式,您可以轻松地将列表框的ItemsSource
属性绑定到我们刚刚创建的数据源。例如,右键单击“对象和时间线”工具面板中的列表框,然后选择“数据绑定项目源到数据..”在弹出的对话框中,您将很容易看到NodesCollectionDataSource
可用且可以使用。
然而,我必须解决的问题......
在我正在阅读的一些书中,他们谈到在Xaml中创建一个CollectionViewSource,可用于排序/分组/过滤/导航其底层数据源。
第一个问题,我在Blend的任何地方都找不到CollectionViewSource;所以唯一的选择是手动在Xaml中创建标签。
只需在Resources块(Xaml)中键入<CollectionViewSource x:Key="cvsNodes" />
,然后从那里,您可以使用Blend GUI修改其他属性;例如,设置基础Source属性和其他Sort和Group Descriptors(可在Resources tools面板下找到)。
现在我们要将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语言的替代品。