У нас есть макет пользовательского интерфейса, который создает список расширителей для ItemsControl
.ItemsControl
имеет имя Items и по соглашению успешно привязывается к нашему внутреннему списку моделей представлений, где наша модель представления имеет тип Conductor<SubViewModel>.Collection.OneActive
my SubViewModel
, равный Screen
, и выглядит следующим образом:
public class SubViewModel : Screen, ISubViewModel
{
public bool IsVisible => true;
public string GroupName => "MyGroupName";
public bool HasValidationFailures => true;
protected override void OnViewLoaded(object view)
{
//overridden to breakpoint on to see when the views get hooked up
}
//various properties and other viewModelly things which should be unimportant
}
В настоящее время ItemsControl
правильно создает Expander
для каждой дочерней модели представления в списке элементов, и содержимое расширителей также правильно находит правильное представление с помощью следующего Xaml:
<ItemsControl x:Name="Items">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="viewModels:SubViewModel">
<Expander Visibility="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
cal:View.ApplyConventions="True"
cal:View.Model="{Binding}">
<Expander.Header>
<WrapPanel>
<TextBlock Text="{Binding GroupName}" />
<ContentControl Style="{StaticResource ErrorIndicator}"
Visibility="{Binding HasValidationFailures, Converter={StaticResource BooleanToVisibilityConverter}}" />
</WrapPanel>
</Expander.Header>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Это облегчает использование разных макетов в соответствии с настройками пользователя.Например, в настоящее время мы привязываем один и тот же проводник к другому представлению, которое вместо этого использует TabControl
и позволяет группам отображаться на отдельных вкладках.Элемент управления вкладками также правильно связывает представление только тогда, когда вкладка выбрана.
После большого количества исследований в Интернете я вполне уверен, что хочу ElementConvention
, но у меня возникают проблемы при разработке того, что мне нужно сделатьчтобы договориться о том, чтобы даже позвонили за Expander
.Я следовал за несколькими примерами, которые я нашел в Интернете, и написал этот код для попытки конвенции:
ConventionManager.AddElementConvention<Expander>(Expander.IsExpandedProperty, "IsExpanded", "IsExpandedChanged")
.ApplyBinding = (viewModelType, path, property, element, convention) =>
{
return true;
};
Однако, если я остановлюсь на этом теле Funcs, он никогда не получит удар, и все представления будут подключеныпри создании Expander
, поэтому я не включил никакой логики, чтобы проверить, развернут ли Expander
...
Я также попытался принудительно установить ApplyConventions
, установив его на расширитель.... это было экспериментально, но в моем Xaml показано для полноты.
Я счастлив исследовать другие маршруты, которые не являются Соглашением о пользовательских элементах, но я действительно не нашел много, что заставило бы меня поверить, что я долженделать это по-другому.