Данные 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}"
Я могу видеть данные времени разработки. Любая идея, что я мог сделать?
Ответы
Ответ 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.