Je suis l'extension ItemsControl
(class EnhancedItemsControl : ItemsControl
), parce que je veux ajouter plusieurs propriétés de dépendance, comme AlternativeContent
qui sera affiché quand il n'y a aucun élément dans la collection (pensez à "entrer un terme de recherche et frapper recherche" étiquette dans un itemscontrol pour les résultats de la recherche). J'ai sous-classé ItemsControl
et ajouté un AlternativeContent
dep. propriété du type FrameworkElement
. Maintenant, je veux fournir un style par défaut dans Themes/Generic.xaml (J'ai ajouté ThemeInfoAttribute
à AsseblyInfo, et fourni des métadonnées en costructor statique comme indiqué dans ce excellent tutorial).WPF - Mise en forme d'un contrôle sans apparence: Comment accéder aux propriétés de dépendance du contrôle à partir du second niveau de ControlTemplates?
Le style contient une ControlTemplate
, et je dois utiliser deuxième ControlTemplate
à l'intérieur du modèle ItemsControl, où ajouter une ContentPresenter
qui devrait montrer l'AlternativeContent
.
Maintenant, mon problème est comment puis-je dire au ContentPresenter
qu'il devrait prendre son contenu du plus haut niveau EnhancedItemsControl
? Si j'étais dans le style de ControlTemplate
, je l'utilise:
Content="{Binding AlternativeContent, RelativeSource={RelativeSource TemplatedParent}}"
mais comme je suis dans l » ControlTemplate
ItemsControl
dans le style de ControlTemplate
, cela ne fonctionne évidemment pas, je aurais besoin de se référer pas modèle parent, mais Toutefois, le modèle TemplateBinding
n'a pas le paramètre AncestorLevel
.
J'ai aussi essayé:
Content="{Binding AlternativeContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WPFControls:EnhancedItemsControl}}}"
mais cela aboutit à vide ContentPresenter
ainsi. Je ne peux pas nommer le TemplatedParent
(parce qu'il est en dehors du ControlTemplate
), donc je ne peux pas me référer à lui par son nom. Je ne peux pas utiliser TemplatedParent
RelativeBinding
, car cela n'atteint pas deux niveaux de modèles de contrôle. Et RelativeSource
FindAncestor
ne fonctionne étrangement pas.
Une idée de comment résoudre ce problème? Je vous remercie!
generic.xaml (extrait):
<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>
Code de contrôle:
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));
}
Utilisation (un List<string>
est fourni 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>
C'est une pièce très cool de travail, je suis heureux que vous » Je l'ai partagé. Je me demande si cela fonctionnera sur mon téléphone WP7 ... –