いくつかの依存プロパティを追加したいので、 ItemsControl
( )を拡張しています-コレクションにアイテムがない場合に表示されるようなものです(検索結果のitemscontrolで「検索語を入力して検索」ラベルを押すと考えてください) )。class EnhancedItemsControl : ItemsControl
AlternativeContent
サブクラス化してdepItemsControl
を追加しました。AlternativeContent
それへのタイプのプロパティFrameworkElement
。ここで、Themes / Generic.xamlでデフォルトのスタイルを提供したいと思います(AsseblyInfoに追加し、この優れたチュートリアルThemeInfoAttribute
で述べたように、静的costructorでメタデータを提供しました)。
スタイルには、が含まれており、 ItemsControlテンプレート内のControlTemplate
2番目を使用する必要があります。ここに、を表示する必要があるを追加します。ControlTemplate
ContentPresenter
AlternativeContent
さて、私の問題はContentPresenter
、トップレベルからコンテンツを取得する必要があることをどのように伝えるEnhancedItemsControl
かです。私がスタイルの中にいた場合ControlTemplate
、私は使用します:
Content="{Binding AlternativeContent, RelativeSource={RelativeSource TemplatedParent}}"
しかし、私はスタイルの内側ItemsControl
にいるので、これは明らかに機能しません。親テンプレートではなく、祖父母テンプレートを参照する必要がありますが、パラメーターがありません。ControlTemplate
ControlTemplate
TemplateBinding
AncestorLevel
私も試しました:
Content="{Binding AlternativeContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WPFControls:EnhancedItemsControl}}}"
しかし、その結果も空ContentPresenter
になります。TemplatedParent
(の外にあるため)名前を付けることがControlTemplate
できないため、名前で参照することはできません。を使用することはできませんTemplatedParent
RelativeBinding
。これは、2つのレベルのコントロールテンプレートに到達しないためです。そしてRelativeSource
FindAncestor
奇妙なことに動作しません。
これを解決する方法はありますか?ありがとうございました!
Generic.xaml(抜粋):
<Style TargetType="{x:Type WPFControls:EnhancedItemsControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type WPFControls:EnhancedItemsControl}">
<ItemsControl
x:Name="RootItemsControl"
ItemsSource="{Binding}"
ItemTemplate="{TemplateBinding ItemTemplate}"
Background="{TemplateBinding Background}"
HorizontalContentAlignment="Stretch"
>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer
x:Name="ContentScrollViewer"
CanContentScroll="False"
>
<StackPanel
x:Name="InnerPanel"
>
<ItemsPresenter
Width="{Binding ActualWidth, ElementName=InnerPanel}"
MaxWidth="{Binding ActualWidth, ElementName=InnerPanel}"
HorizontalAlignment="Stretch"
/>
<ContentPresenter
Content="{Binding AlternativeContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WPFControls:EnhancedItemsControl}}}"
>
<ContentPresenter.Style>
<Style>
<Setter Property="ContentPresenter.Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger
Binding="{Binding Items.Count, ElementName=RootItemsControl}"
Value="0">
<Setter Property="ContentPresenter.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
制御コード:
public class EnhancedItemsControl : ItemsControl
{
static EnhancedItemsControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(EnhancedItemsControl),
new FrameworkPropertyMetadata(typeof(EnhancedItemsControl)));
}
public FrameworkElement AlternativeContent
{
get { return (FrameworkElement)GetValue(AlternativeContentProperty); }
set { SetValue(AlternativeContentProperty, value); }
}
// Using a DependencyProperty as the backing store for AlternativeContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AlternativeContentProperty =
DependencyProperty.Register("AlternativeContent", typeof(FrameworkElement), typeof(EnhancedItemsControl), new UIPropertyMetadata(null));
}
使用法(aList<string>
はとして提供されますDataContext
):
<WPFControls:EnhancedItemsControl Height="120" x:Name="EnhancedCollection"
>
<WPFControls:EnhancedItemsControl.AlternativeContent>
<WPFControls:CenteredLabel>
Alternative content
</WPFControls:CenteredLabel>
</WPFControls:EnhancedItemsControl.AlternativeContent>
<WPFControls:EnhancedItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</WPFControls:EnhancedItemsControl.ItemTemplate>
</WPFControls:EnhancedItemsControl>