DependencyProperty编译和工作,但Intellisense不这么认为

时间:2015-07-18 01:18:15

标签: c# wpf visual-studio-2012 wpf-controls wpf-4.0

我有两个自定义控件/视觉效果,我需要两个Orientation属性。在这两种情况下,默认值应为"Horizontal",但控件/视觉用户应该能够指定Orientation="Vertical"来垂直排列控件/视觉组件。我的ImageButton控件的效果非常好,但在我的HeaderedLabel视觉效果上效果不是很好。尽管两者都编译良好,但Intellisense并不喜欢其中之一。以下是他们使用的一个例子......

<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"/>

...在垂直StackPanel中渲染时产生以下内容:

Rendered controls/visuals

所以它做了我想要的,但问题是:虽然Intellisense识别出ImageButton的Orientation的可能选项, 但它无法识别的可能选项 Orientation for HeaderedLabel 。虽然代码编译和放大运行正常, Visual Studio“错误列表”窗格中存在持久性错误: “'垂直'不是属性'Orientation'的有效值。”, 在上面的xaml示例中,第二个HeaderedLabel文本 Orientation="Vertical"下面有一条蓝色波浪线。

以下是相关文件:

// 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>

为什么编译器会将Orientation.Horizontal解析为ImageButton的System.Windows.Controls.Orientation.Horizo​​ntal,而不是HeaderedLabel?更重要的是,为什么Intellisense无法找出HeaderedLabel.Orientation的选项?

BTW,我正在使用VisualStudio 2012和.NET Framework 4.0。

1 个答案:

答案 0 :(得分:3)

您的所有属性(包括Orientation属性)都声明为object类型。

你应该改为:

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

如果正确声明属性,XAML编辑器应该能够正确接受Orientation类型的值。否则,它将尝试将string"Vertical"分配给属性,当传递给SetValue()方法时,该属性将失败,因为DependencyProperty对象本身已初始化为Orientation作为有效类型,无法将string值转换为Orientation值。

如果你正确地声明了属性,那么WPF会自动理解它需要将XAML中显示的string值转换为属性的Orientation值(即解析string } value作为适当的enum类型),在这种情况下初始化应该有效。