Есть базовый класс Action
обозначающий действие:
public class BaseAction
{
public string Name {get;set;}
}
И есть класс-наследник ExpanderAction
, который обозначает череду таких действий:
public class ExpanderAction : BaseAction
{
public List<BaseAction> Actions {get;set;} = new List<BaseAction>();
}
Также существует коллекция элементов, которая привязана к ItemsControl
:
public ObservableCollection<BaseAction> Actions {get;set;} = new ObservableCollection<BaseAction>();
Элементы коллекции могут быть представлены 2 видами:
кнопкой или другой коллекцией с элементами. Нужный шаблон выбирается через ItemTemplateSelector
.
<DataTemplate x:Key="BaseActionTemplate" DataType="{x:Type actions:BaseAction}">
<Button Content="{Binding Name}" />
</DataTemplate>
<DataTemplate x:Key="ExpanderActionTemplate" DataType="{x:Type actions:ExpanderAction}">
<ItemsControl ItemsSource="{Binding Actions}" />
</DataTemplate>
Проблема в том, что внутри ItemsControl
, который лежит в шаблоне ExpanderActionTemplate
элементы нужно отобразить также 2-я теми же самыми шаблонами.
Получается что-то вроде рекурсии.
Подскажите, как указать внутри ExpanderActionTemplate
, что данные в ItemsControl
должны отображаться его же шаблоном?
Update
Делаю так, но возникает ошибка на строке Second="{StaticResource Second}"
. Это происходит из-за того, что селектор объявлен раньше, чем шаблон данных Second
.
<Window.Resources>
<DataTemplate x:Key="First">
<Button Content="{Binding Name}" />
</DataTemplate>
<local:Selector x:Key="Selector"
First="{StaticResource First}"
Second="{StaticResource Second}"/>
<DataTemplate x:Key="Second">
<ItemsControl ItemTemplateSelector="{StaticResource Selector}"
ItemsSource="{Binding Path=ChildActions}"/>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ItemsControl ItemsSource="{Binding Actions}"
ItemTemplateSelector="{StaticResource Selector}" />
</StackPanel>
У меня компилируется так:
<Window.Resources>
<DataTemplate x:Key="First">
<Button Content="{Binding Name}" />
</DataTemplate>
<DataTemplate x:Key="Second">
<ItemsControl ItemTemplateSelector="{DynamicResource Selector}"
ItemsSource="{Binding Path=ChildActions}"/>
</DataTemplate>
<local:Selector x:Key="Selector"
First="{StaticResource First}"
Second="{StaticResource Second}"/>
</Window.Resources>
(хотя и с предупреждением).
Если вы не хотите использовать DynamicResource
, можно обойтись и без него за счёт code-behind:
<Window.Resources>
<local:Selector x:Key="Selector"/>
<DataTemplate x:Key="First">
<Button Content="{Binding Name}" />
</DataTemplate>
<DataTemplate x:Key="Second">
<ItemsControl ItemTemplateSelector="{StaticResource Selector}"
ItemsSource="{Binding Path=ChildActions}"/>
</DataTemplate>
</Window.Resources>
public MainWindow()
{
InitializeComponent();
// обязательно после InitializeComponent
var selector = (Selector)Resources["Selector"];
selector.First = (DataTemplate)Resources["First"];
selector.Second = (DataTemplate)Resources["Second"];
}
Можно найти родительский ItemsControl
и забрать у него свойство ItemTemplateSelector
:
<DataTemplate x:Key="ExpanderActionTemplate" DataType="{x:Type actions:ExpanderAction}">
<ItemsControl ItemsSource="{Binding Actions}"
ItemTemplateSelector="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=ItemTemplateSelector}"/>
</DataTemplate>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть jsonПытаюсь через Newtonsoftjson привести его к классу
Люди добрые, помогите установить компонент scintilla visual studio 2010Компонент добавляется, но при добавлении в форму выдает ошибку