2

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 » ControlTemplateItemsControl 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 TemplatedParentRelativeBinding, car cela n'atteint pas deux niveaux de modèles de contrôle. Et RelativeSourceFindAncestor 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> 

Répondre

1

Oops, mon mauvais,

Content="{Binding AlternativeContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WPFControls:EnhancedItemsControl}}}" 

fonctionne réellement (mais mon balisage était plus compliqué que celui de l'exemple, et le contenu n'a pas été démontré que d'autres bug ...)

+0

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 ... –

Questions connexes