Могу ли я иметь два ContentPresenter, указывающие на один Content или ContentSource в ContentTemplate?
Я создал NavigationPane точно так же, как Outlook 2007. В Outlook, когда панель свернута и нажата боковая панель, она использовалась для вызова содержимого Selected NavigationItem. Я имитировал то же поведение, используя contentpresenter в ControlTemplete (один для SelectItemHost TabControl и другой для Popup). Но проблема в том, что когда всплывающее окно открыто, NavigationPane выбирает содержимое, когда оно отсутствует, и оно появляется, когда мы снова переключаемся на тот же элемент навигации с другого элемента навигации. Я использую TabControl и TabItem в качестве NavigationPane и NavigationPaneItem.
Я указываю "SelectedContent" как ContentSource для двух ContentPresenter
1 ответ
Вы можете определить два ContentPresenter
объекты в шаблоне элемента управления и укажите их на один и тот же источник контента, если хотите:
<ControlTemplate x:Key="WeirdButton" TargetType="Button">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.RowSpan="2" Background="{TemplateBinding Background}" />
<ContentPresenter ContentSource="Content"/>
<ContentPresenter ContentSource="Content" Grid.Row="1"/>
</Grid>
</ControlTemplate>
Однако это имеет некоторые довольно необычные побочные эффекты. Поскольку вы не можете поместить один и тот же визуал в два места в дереве визуалов, этот шаблон будет работать, как и ожидалось, только если дочерний контент кнопки НЕ является визуалом (или получен из Visual). Если содержимое - это какой-то другой тип данных, а визуальные элементы создаются шаблоном данных, все работает должным образом. Установка содержимого кнопки в строку (<Button Content="OK"/>
) работает также.
Обратите внимание, что этот же эффект может быть достигнут с помощью визуальной кисти:
<ControlTemplate x:Key="WeirdButton" TargetType="Button">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.RowSpan="2" Background="{TemplateBinding Background}" />
<ContentPresenter x:Name="presenter" ContentSource="Content"/>
<Rectangle Grid.Row="1"
Width="{Binding ActualWidth, ElementName=presenter}" Height="{Binding ActualHeight, ElementName=presenter}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=presenter}" Stretch="None" AlignmentX="Left"/>
</Rectangle.Fill>
</Rectangle>
</Grid>
</ControlTemplate>
Недостаток этого подхода заключается в том, что вы не можете взаимодействовать с элементами управления в визуальной кисти. Поэтому, если вы хотите, чтобы кнопки, текстовые поля и другие элементы управления на дубликате также были интерактивными, вам нужно будет придерживаться подхода, более близкого к первому шаблону.