2015-07-18 2 views
2

J'ai deux contrôles/visuels personnalisés et j'ai besoin d'une propriété Orientation sur les deux. Dans les deux cas, la valeur par défaut doit être "Horizontal" mais l'utilisateur du contrôle/visuel doit pouvoir spécifier Orientation="Vertical" pour organiser verticalement les composants du contrôle/visuel. Ce que j'ai fonctionne bien sur mon contrôle ImageButton, mais pas si bien sur mon visuel HeaderedLabel. Bien que les deux compilent bien, Intellisense n'aime pas l'un d'entre eux. Voici un exemple de leur utilisation ...DependencyProperty se compile et fonctionne mais Intellisense ne le pense pas

<Visuals:ImageButton Image="Icons/ok.png" Content="Normal Content"/> 
<Visuals:ImageButton Image="Icons/ok.png" Content="Vertical Content" Orientation="Vertical"/> 
<Visuals:HeaderedLabel Header="Normal Header" Content="Normal Content"/> 
<Visuals:HeaderedLabel Header="Vertical Header" Content="Vertical Content" Orientation="Vertical"/> 

... qui produit les éléments suivants lorsqu'ils sont rendus dans un StackPanel vertical:

Rendered controls/visuals

Il fait ce que je veux, mais le problème est ceci: Alors que Intellisense reconnaît les options possibles pour Orientation pour le ImageButton, il ne reconnaît pas les options possibles pourOrientationpour le HeaderedLabel. Et tandis que le code compile & fonctionne bien, il y a une erreur persistante dans la « Liste d'erreurs » Visual Studio volet: « « verticale » est pas une valeur valide pour la propriété « Orientation ». », et il y a un bleu ligne ondulée sous le texteOrientation="Vertical" pour la deuxième HeaderedLabel dans mon exemple xaml ci-dessus.

Voici les fichiers pertinents:

// File 'ImageButton.cs' 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace Visuals 
{ 
    public class ImageButton : Button 
    { 
     static ImageButton() 
     { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), 
      new FrameworkPropertyMetadata(typeof(ImageButton))); 
     } 

     public ImageSource Image 
     { 
     get { return (ImageSource)GetValue(ImageProperty); } 
     set { SetValue(ImageProperty, value); } 
     } 

     public Orientation Orientation 
     { 
     get { return (Orientation)GetValue(OrientationProperty); } 
     set { SetValue(OrientationProperty, value); } 
     } 

     // Note that for ImageButton, I can just say 'Orientation.Horizontal' and 
     // the compiler resolves that to System.Windows.Controls.Orientation... 
     public static readonly DependencyProperty OrientationProperty = 
     DependencyProperty.Register("Orientation", typeof(Orientation), 
      typeof(ImageButton), new UIPropertyMetadata(Orientation.Horizontal)); 

     public static readonly DependencyProperty ImageProperty = 
     DependencyProperty.Register("Image", typeof(ImageSource), 
      typeof(ImageButton), new UIPropertyMetadata(null)); 
    } 
} 

.

// File 'HeaderedLabel.cs' 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace Visuals 
{ 
    public class HeaderedLabel : Control 
    { 
     static HeaderedLabel() 
     { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(HeaderedLabel), 
      new FrameworkPropertyMetadata(typeof(HeaderedLabel))); 
     } 

     public object Header 
     { 
     get { return (object)GetValue(HeaderProperty); } 
     set { SetValue(HeaderProperty, value); } 
     } 

     public object Content 
     { 
     get { return (object)GetValue(ContentProperty); } 
     set { SetValue(ContentProperty, value); } 
     } 

     public object Orientation 
     { 
     get { return (object)GetValue(OrientationProperty); } 
     set { SetValue(OrientationProperty, value); } 
     } 

     public static readonly DependencyProperty HeaderProperty = 
     DependencyProperty.Register("Header", typeof(object), typeof(HeaderedLabel), 
      new UIPropertyMetadata(null)); 

     public static readonly DependencyProperty ContentProperty = 
     DependencyProperty.Register("Content", typeof(object), typeof(HeaderedLabel), 
      new UIPropertyMetadata(null)); 

     // Note that for HeaderedLabel, unlike ImageButton, I have to specify the fully- 
     // qualified name of 'Orientation.Horizontal', otherwise the compiler resolves it 
     // to Visuals.HeaderedLabel.Orientation and gives a compiler error... 
     public static readonly DependencyProperty OrientationProperty = 
     DependencyProperty.Register("Orientation", typeof(System.Windows.Controls.Orientation), 
      typeof(HeaderedLabel), new UIPropertyMetadata(System.Windows.Controls.Orientation.Horizontal)); 
    } 
} 

.

<!-- File 'Generic.xaml' --> 
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
         xmlns:local="clr-namespace:Visuals" 
         xmlns:bind="clr-namespace:Visuals.BindingConverters"> 

     <Style TargetType="{x:Type local:ImageButton}"> 
      <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:ImageButton}"> 
        <Button> 
         <StackPanel Orientation="{TemplateBinding Orientation}"> 
         <Image Source="{TemplateBinding Image}"/> 
         <ContentPresenter/> 
         </StackPanel> 
        </Button> 
       </ControlTemplate> 
      </Setter.Value> 
      </Setter> 
     </Style> 

     <Style TargetType="{x:Type local:HeaderedLabel}"> 
      <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:HeaderedLabel}"> 
        <StackPanel Orientation="{TemplateBinding Orientation}"> 
         <StackPanel Orientation="Horizontal"> 
         <ContentControl Content="{TemplateBinding Header}" /> 
         <TextBlock Text=":" /> 
         </StackPanel> 
         <ContentControl Content="{TemplateBinding Content}"/> 
        </StackPanel> 
       </ControlTemplate> 
      </Setter.Value> 
      </Setter> 
     </Style> 

    </ResourceDictionary> 

Toutes les idées pourquoi le compilateur résoudre Orientation.Horizontal à System.Windows.Controls.Orientation.Horizontal pour le ImageButton, mais pas pour le HeaderedLabel? Et plus important encore, des idées pour lesquelles Intellisense ne peut pas comprendre les options pour HeaderedLabel.Orientation?

BTW, j'utilise VisualStudio 2012 et .NET Framework 4.0.

+1

Impossible de reproduire un problème avec typeof (System.Windows.Controls.Orientation) dont vous parlez dans les commentaires sur la déclaration Dependency Property, mais pour xaml, la solution Intellisense est simple: regardez de plus près votre déclaration de propriété ordinaire. Dans ImageButton, vous avez 'Orientation Orientation' (à droite), dans HeaderedLabel vous avez' object Orientation' (faux) – Aloraman

Répondre

3

Toutes vos propriétés, y compris la propriété Orientation, sont déclarées comme ayant le type object.

Vous devez avoir ceci:

public Orientation Orientation 
{ 
    get { return (Orientation)GetValue(OrientationProperty); } 
    set { SetValue(OrientationProperty, value); } 
} 

L'éditeur XAML devrait être en mesure d'accepter correctement les valeurs de type Orientation si vous déclarez la propriété correctement. Sinon, il tentera d'affecter une valeur string de "Vertical" à la propriété, qui, lorsqu'elle sera transmise à la méthode SetValue(), échouera, car l'objet DependencyProperty lui-même a été initialisé avec Orientation comme type valide et n'a aucun moyen de convertir à partir de la valeur string. à une valeur Orientation.

Si vous déclarez la propriété correctement, WPF comprendra automatiquement qu'il doit convertir la valeur string indiqué dans le XAML à une valeur Orientation pour la propriété (par exemple analyser la valeur string comme le type enum approprié), et Dans ce cas, l'initialisation devrait fonctionner.

+0

Merci, c'était le problème. Erreur de couper-coller stupide. En ce qui concerne les autres propriétés, Header et Content, devraient-ils être quelque chose d'autre, ou est-ce que le type 'object' est le meilleur choix? (Ils sont tous les deux juste des chaînes libres de tout ce que l'utilisateur veut qu'ils soient.) – phonetagger

+0

Aussi, comme vous ne blessez pas pour rep, préféreriez-vous que je supprime juste cette question car c'est juste une erreur de copier-coller? – phonetagger

+0

La question pourrait sans doute être fermée sous la raison "erreur typographique", donc suppression pourrait être appropriée. Ce serait vrai quelle que soit la représentante que j'ai. :) Alors n'hésitez pas à le faire, si vous pensez que le problème a été résolu d'une manière qui ne sera probablement pas utile à d'autres personnes cherchant Stack Overflow plus tard. Je noterai que votre question est la seule avec à la fois la phrase _ "n'est pas une valeur valide pour la propriété" _ et le mot _ "Intellisense" _, donc réfléchissez si quelqu'un d'autre pourrait commettre une erreur similaire et s'ils seraient susceptible de trouver cela en cherchant. –