Подтвердить что ты не робот

Данные DesignTime не отображаются в Blend при привязке к CollectionViewSource

У меня есть datatemplate для viewmodel, где элемент управления связан с 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, данные времени разработки не отображаются в смешении 3. Когда я напрямую привязываюсь к коллекции ViewModel

<ItemsControl ItemsSource="{Binding Modules}"

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

Не уверен, что это все еще актуально... недавно была аналогичная проблема - я все еще где-то на кривой обучения 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; например, устанавливая базовое свойство Source и дополнительные дескрипторы сортировки и группы (найдены в панели инструментов "Ресурсы" ).

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

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

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

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

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

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

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