Данные DesignTime не отображаются в Blend при привязке к CollectionViewSource - PullRequest
15 голосов
/ 19 сентября 2009

У меня есть таблица данных для модели представления, в которой элемент управления контентом привязан к 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}">

Это в основном статическое свойство, которое дает мне EquipmentViewModel со списком ModuleViewModels (Equipment.Modules). Теперь, пока я связываюсь с CollectionViewSource, данные времени разработки не отображаются в blend 3. Когда я связываюсь с коллекцией ViewModel напрямую

<ItemsControl ItemsSource="{Binding Modules}"

Я вижу данные времени разработки. Любая идея, что я мог сделать?

Ответы [ 3 ]

7 голосов
/ 21 апреля 2011

Было сделано это (теперь, по крайней мере):)

Это решение, которое я нашел. Хитрость заключается в том, чтобы переопределить источник для времени разработки 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>
0 голосов
/ 10 апреля 2013

Не уверен, что это все еще актуально ... недавно была похожая проблема - я все еще где-то на кривой обучения WPF , просто не совсем уверен, где ...

В любом случае, вот сценарий: я хотел бы создать объект типа ObservableCollection где-нибудь в моем локальном пространстве имен (для простоты), например ..

public class NodesCollection : ObservableCollection<Nodes> { }

Затем из Blend / Xaml я могу легко «Создать источник данных объекта» (из панели инструментов «Данные») и найти, что NodesCollection отображается и может быть выбрано.

Затем Blend создаст локальный ресурс в верхней части файла Xaml, аналогично:

<local:NodesCollection x:Key="NodesCollectionDataSource" d:IsDataSource="True" />

С этим вы можете легко привязать свойство ItemsSource списка к источнику данных, который мы только что создали. Например, щелкните правой кнопкой мыши по списку на панели инструментов «Объекты и временная шкала» и выберите «Привязать данные к элементу Источники данных». Во всплывающем диалоговом окне вы увидите, что NodesCollectionDataSource доступен и может использоваться. *

Однако здесь возникают проблемы, которые мне пришлось решить ...

В некоторых книгах, которые я читаю в данный момент, они говорят о создании CollectionViewSource в Xaml, который можно использовать для сортировки / группировки / фильтрации / навигации по исходному источнику данных.

Первая проблема, я не могу найти CollectionViewSource нигде в Blend; поэтому единственный вариант - создать тег в Xaml вручную.

Просто введите <CollectionViewSource x:Key="cvsNodes" /> в блоке ресурсов (Xaml), и оттуда вы можете изменять дополнительные свойства, используя Blend GUI; например, установка основного свойства Source и дополнительных дескрипторов Sort и Group (находится на панели инструментов Resources).

Теперь наступает момент, когда мы хотим связать свойство ItemsBource ListBox с CollectionViewSource. Однако вы не сможете найти этот предмет, используя Blend GUI. Поэтому вы должны ввести значение привязки вручную. Например:

<ListBox x:Name=.. ItemsSource="{Binding Source={DynamicResource cvsNodes}}".. />

Это работает. Но чтобы сделать это еще проще, нам нужно вернуться к исходному элементу ресурса CollectionViewSource в Xaml и добавить дополнительный атрибут:

<CollectionViewSource x:Key="cvsNodes" Source=... d:IsDataSource="True"

d:IsDataSource="True" позволяет добиться того, чтобы Blend GUI распознал этот ресурс как доступный для использования.

Теперь, если мы вернемся к свойству ItemsSource в ListBox на панели инструментов Свойства, мы сможем выбрать cvsNodes из списка доступных источников данных.

Надеюсь, это поможет любому, кто, возможно, пришёл к тому же выводу, что и я, что Blend и лежащая в основе технология Xaml не полностью синхронизированы; и что Blend в лучшем случае является инструментом для создания Xaml, а не заменой для изучения языка Xaml.

0 голосов
/ 18 марта 2011
  1. Я не уверен, что x:Static должен работать в d:DataContext, думаю, только d: DesignInstance или d:DesignData могли бы.
  2. Вы проверяли данные времени проектирования и уверены, что они действительно заполнены данными?
  3. Попробуйте указать свойство d:IsDesignTimeCreatable=True в d: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) для шаблонов или стилей, которые не предназначены для изменения во время выполнения. Прочитайте это для получения дополнительной информации.

...