15

我有一个视图模型的数据模板,其中项目控件绑定到 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}"

我可以看到设计时数据。知道我能做什么吗?

4

3 回答 3

7

去过那里(至少现在):)

这是我找到的解决方案。诀窍是覆盖 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>
于 2011-04-21T09:17:22.677 回答
0

不确定这是否仍然相关......最近有一个类似的问题 - 我仍然在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 中手动创建标签。

只需<CollectionViewSource x:Key="cvsNodes" />在 Resources 块 (Xaml) 中输入,您就可以使用 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 语言的替代品。

于 2013-04-10T03:01:32.860 回答
0
  1. 我不确定x:Static是否应该工作d:DataContext,我认为只有 d:DesignInstance 或d:DesignData可以。
  2. 您是否测试了设计时数据并确定确实充满了数据?
  3. 尝试d:IsDesignTimeCreatable=Trued:DesignInstance.
  4. 尽管是 Silverlight 特有的,但我相信它可能会给您一些提示。

它通常应该是这样的:

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)用于在运行时不会更改的模板或样式。阅读内容以获取更多信息。

于 2011-03-18T03:50:59.007 回答