2016-06-14 46 views
0

我一直在我的头上撞墙,现在好几天了,我似乎无法找到任何适合我的问题的信息。用户控件上的WPF按钮属性不显示属性窗格中的属性

所以,我有这个工具栏用户控件,这意味着要放入应用程序。这个工具栏有一个名为“FullExtentButton”的属性,它是对按钮的引用。我想要的是在工具栏用户控件的设计器属性窗格中公开此按钮的属性,以便开发人员可以直接从设计器中设置属性。

在WinForms中,这很容易做到。 WPF,不是那么多(除非我只是盲目的)。

在我的工具栏的代码:

[Category("Standard Buttons")] 
[Browsable(true)] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
public MyToolbarButton FullExtentButton 
{ 
    get; 
    private set; 
} 

此值在构造函数中设置的用户控件:

public MyToolbar() 
{ 
    InitializeComponent(); 

    FullExtentButton = new MyToolbarButton("FullExtent", "/Utilities;component/Resources/full_extent_16x16.png"); 
} 

按钮本身很简单:

public class MyToolbarButton 
    : Freezable 
{ 
    #region Dependency Properties. 
    /// <summary> 
    /// Dependency property for the <see cref="IsVisible"/> property. 
    /// </summary> 
    public static DependencyProperty IsVisibleProperty =  DependencyProperty.Register("IsVisible", typeof(bool), typeof(MyToolbarButton), 
                           new FrameworkPropertyMetadata(true, 
                                  FrameworkPropertyMetadataOptions 
                                  .BindsTwoWayByDefault, Visible_Changed)); 
/// <summary> 
/// Dependency property for the <see cref="IsEnabled"/> property. 
/// </summary> 
public static DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof(bool), typeof(MyToolbarButton), 
                       new FrameworkPropertyMetadata(true, 
                               FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Enabled_Changed)); 

/// <summary> 
/// Dependency property for the <see cref="ToolTip"/> property. 
/// </summary> 
public static DependencyProperty ToolTipProperty = DependencyProperty.Register("ToolTip", typeof(string), typeof(MyToolbarButton), 
                       new FrameworkPropertyMetadata(string.Empty, 
                               FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ToolTip_Changed)); 

/// <summary> 
/// Dependency property for the <see cref="Glyph"/> property. 
/// </summary> 
public static DependencyProperty GlyphProperty = DependencyProperty.Register("Glyph", typeof(ImageSource), typeof(MyToolbarButton), 
                       new FrameworkPropertyMetadata(null, 
                               FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Glyph_Changed)); 

/// <summary> 
/// Dependency property for the <see cref="ID"/> property. 
/// </summary> 
public static DependencyProperty IDProperty = DependencyProperty.Register("ID", typeof(string), typeof(MyToolbarButton), 
                      new FrameworkPropertyMetadata(string.Empty, 
                             FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

/// <summary> 
/// Dependency property for the <see cref="ClickedCommand"/> property. 
/// </summary> 
public static DependencyProperty ClickedCommandProperty = DependencyProperty.Register("ClickedCommand", typeof(IMyRelayCommand<string>), 
    typeof(MyToolbarButton), 
    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 
#endregion 

#region Variables. 
// The default image source for the button glyph. 
private readonly Uri _defaultImageSource; 
#endregion 

#region Properties. 
/// <summary> 
/// Property to set or return the command to execute when the button is clicked. 
/// </summary> 
public IMyRelayCommand<string> ClickedCommand 
{ 
    get 
    { 
     return (IMyRelayCommand<string>)GetValue(ClickedCommandProperty); 
    } 
    set 
    { 
     SetValue(ClickedCommandProperty, value); 
    } 
} 


/// <summary> 
/// Property to set or return the ID of the button. 
/// </summary> 
public string ID 
{ 
    get 
    { 
     object value = GetValue(IDProperty); 

     return value == null ? string.Empty : value.ToString(); 
    } 
    set 
    { 
     SetValue(IDProperty, value); 
    } 
} 

/// <summary> 
/// Property to set or return the glyph for this button. 
/// </summary> 
public ImageSource Glyph 
{ 
    get 
    { 
     return GetValue(GlyphProperty) as ImageSource; 
    } 
    set 
    { 
     SetValue(GlyphProperty, value); 
    } 
} 

/// <summary> 
/// Property to set or return the tool tip for the button. 
/// </summary> 
public string ToolTip 
{ 
    get 
    { 
     object value = GetValue(ToolTipProperty); 

     return value == null ? string.Empty : value.ToString(); 
    } 
    set 
    { 
     SetValue(ToolTipProperty, value); 
    } 
} 

/// <summary> 
/// Property to set or return whether the button is visible or not. 
/// </summary> 
public bool IsVisible 
{ 
    get 
    { 
     return (bool)GetValue(IsVisibleProperty); 
    } 
    set 
    { 
     SetValue(IsVisibleProperty, value); 
    } 
} 

/// <summary> 
/// Property to set or return whether the button is enabled or not. 
/// </summary> 
public bool IsEnabled 
{ 
    get 
    { 
     return (bool)GetValue(IsEnabledProperty); 
    } 
    set 
    { 
     SetValue(IsEnabledProperty, value); 
    } 
} 
#endregion 

#region Methods. 
/// <summary> 
/// Function to handle a change to the <see cref="GlyphProperty"/>. 
/// </summary> 
/// <param name="sender">The sender of the event.</param> 
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
private static void Glyph_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
{ 
    // TODO 
} 

/// <summary> 
/// Function to handle a change to the <see cref="IsVisibleProperty"/>. 
/// </summary> 
/// <param name="sender">The sender of the event.</param> 
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
private static void Visible_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
{ 
    // TODO 
} 

/// <summary> 
/// Function to handle a change to the <see cref="IsEnabledProperty"/>. 
/// </summary> 
/// <param name="sender">The sender of the event.</param> 
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
private static void Enabled_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
{ 
    // TODO 
} 

/// <summary> 
/// When implemented in a derived class, creates a new instance of the <see cref="T:System.Windows.Freezable" /> derived class. 
/// </summary> 
/// <returns>The new instance.</returns> 
protected override Freezable CreateInstanceCore() 
{ 
    return new MyToolbarButton(); 
} 
#endregion 

#region Constructor/Finalizer. 
/// <summary> 
/// Initializes a new instance of the <see cref="MyToolbarButton"/> class. 
/// </summary> 
/// <param name="buttonID">The ID of the button being clicked.</param> 
/// <param name="defaultImageSource">The default image source URI for the glyph used by the button.</param> 
internal MyToolbarButton(string buttonID, string defaultImageSource) 
{ 
    ID = buttonID; 
    IsVisible = true; 
    IsEnabled = true; 
    ToolTip = string.Empty; 

    if (!string.IsNullOrWhiteSpace(defaultImageSource)) 
    { 
     _defaultImageSource = new Uri(defaultImageSource, UriKind.Relative); 
    } 
} 

/// <summary> 
/// Initializes a new instance of the <see cref="MyToolbarButton"/> class. 
/// </summary> 
public MyToolbarButton() 
{ 
    // This is here to keep the XAML designer from complaining.   
} 
#endregion 

但,当我在XAML设计器中查看我的用户控件上的button属性并展开它的属性时,我得到:

NoProperties

正如你所看到的,有在XAML设计器下没有任何属性。我想要的是让该按钮的属性显示在“FullExtentsButton”属性下,以便我的开发人员可以修改属性,但而不是能够创建/删除已存在的实例。

我已经尝试使我的UserControl上的FullExtentButton属性DependencyProperty,但这并没有解决任何问题。

这是我们希望跨应用程序使用的标准工具栏的一部分,因此强化一致性对我们来说非常重要。此外,它将允许我们的开发人员专注于应用程序的其他部分,而不是一遍又一遍地重复实现相同的事情(这正是我们现在必须要做的)。

所以,说,我在我的智慧结束在这里,我做错了什么?

+0

我这样做的方式是创建包含小部件的全面usercontrols,例如MyToolBar Button是一个usercontrol而不是一个可冻结的。这不仅允许道具显示在属性页上,而且还可以将控件拖放到任何父级控件中。在你的情况下,你有两个用户控件1)MyToolBar和2)MyToolBarButton,将MyToolbarButton拖到MyToolbar中,属性应该显示出来。 –

+0

这就是我所说的遏制。 “赞成继承”一旦你拨入这个概念,它非常酷! –

+0

我尝试使用UserControl,但它有相同的结果。 这样做的目的是使按钮成为工具栏的永久部分,也就是说,不允许用户添加或删除它。这是一个标准的工具栏,它被放入并命令绑定到视图模型的标准按钮。我们正在这样做,以便我们的开发人员不必为自己做额外的工作,并减少使用这些功能所需的时间(此外,它提供了将在其中使用的应用程序的一致性)。 – Mike

回答

0

使用这个代码,我不得不有所变化,以获得它来编译....

/// <summary> 
/// Interaction logic for MyToolBarButton.xaml 
/// </summary> 
public partial class MyToolBarButton : UserControl 
{ 
    public MyToolBarButton() 
    { 
     InitializeComponent(); 
    } 
     #region Dependency Properties. 
    /// <summary> 
    /// Dependency property for the <see cref="IsVisible"/> property. 
    /// </summary> 
    public static DependencyProperty IsVisibleProperty = DependencyProperty.Register("IsVisible", typeof(bool), typeof(MyOldToolBarButton), 
                           new FrameworkPropertyMetadata(true, 
                                  FrameworkPropertyMetadataOptions 
                                  .BindsTwoWayByDefault, Visible_Changed)); 
    /// <summary> 
    /// Dependency property for the <see cref="IsEnabled"/> property. 
    /// </summary> 
    public static DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof(bool), typeof(MyOldToolBarButton), 
                        new FrameworkPropertyMetadata(true, 
                                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Enabled_Changed)); 

    /// <summary> 
    /// Dependency property for the <see cref="ToolTip"/> property. 
    /// </summary> 
    public static DependencyProperty ToolTipProperty = DependencyProperty.Register("ToolTip", typeof(string), typeof(MyOldToolBarButton), 
                        new FrameworkPropertyMetadata(string.Empty, 
                                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
                                 new PropertyChangedCallback(ToolTipPropertyChanged))); 

    private static void ToolTipPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 



    /// <summary> 
    /// Dependency property for the <see cref="Glyph"/> property. 
    /// </summary> 
    public static DependencyProperty GlyphProperty = DependencyProperty.Register("Glyph", typeof(ImageSource), typeof(MyOldToolBarButton), 
                        new FrameworkPropertyMetadata(null, 
                                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Glyph_Changed)); 

    /// <summary> 
    /// Dependency property for the <see cref="ID"/> property. 
    /// </summary> 
    public static DependencyProperty IDProperty = DependencyProperty.Register("ID", typeof(string), typeof(MyOldToolBarButton), 
                       new FrameworkPropertyMetadata(string.Empty, 
                              FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

    /// <summary> 
    /// Dependency property for the <see cref="ClickedCommand"/> property. 
    /// </summary> 
    public static DependencyProperty ClickedCommandProperty = DependencyProperty.Register("ClickedCommand", typeof(string), 
     typeof(MyOldToolBarButton), 
     new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 
    #endregion 

    #region Variables. 
    // The default image source for the button glyph. 
    public Uri _defaultImageSource { private set; get; } 
    #endregion 

    #region Properties. 



    /// <summary> 
    /// Property to set or return the ID of the button. 
    /// </summary> 

    [Category("Configuration")] 
    public string ID 
    { 
     get 
     { 
      object value = GetValue(IDProperty); 

      return value == null ? string.Empty : value.ToString(); 
     } 
     set 
     { 
      SetValue(IDProperty, value); 
     } 
    } 

    /// <summary> 
    /// Property to set or return the glyph for this button. 
    /// </summary> 

    [Category("Configuration")] 
    public ImageSource Glyph 
    { 
     get 
     { 
      return GetValue(GlyphProperty) as ImageSource; 
     } 
     set 
     { 
      SetValue(GlyphProperty, value); 
     } 
    } 

    /// <summary> 
    /// Property to set or return the tool tip for the button. 
    /// </summary> 
    /// 

    [Category("Configuration")] 
    public string ToolTip 
    { 
     get 
     { 
      object value = GetValue(ToolTipProperty); 

      return value == null ? string.Empty : value.ToString(); 
     } 
     set 
     { 
      SetValue(ToolTipProperty, value); 
     } 
    } 

    /// <summary> 
    /// Property to set or return whether the button is visible or not. 
    /// </summary> 
    /// 
    [Category("Configuration")] 
    public bool IsVisible 
    { 
     get 
     { 
      return (bool)GetValue(IsVisibleProperty); 
     } 
     set 
     { 
      SetValue(IsVisibleProperty, value); 
     } 
    } 

    /// <summary> 
    /// Property to set or return whether the button is enabled or not. 
    /// </summary> 
    /// 
    [Category("Configuration")] 
    public bool IsEnabled 
    { 
     get 
     { 
      return (bool)GetValue(IsEnabledProperty); 
     } 
     set 
     { 
      SetValue(IsEnabledProperty, value); 
     } 
    } 
    #endregion 

    #region Methods. 
    /// <summary> 
    /// Function to handle a change to the <see cref="GlyphProperty"/>. 
    /// </summary> 
    /// <param name="sender">The sender of the event.</param> 
    /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
    private static void Glyph_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     // TODO 
    } 

    /// <summary> 
    /// Function to handle a change to the <see cref="IsVisibleProperty"/>. 
    /// </summary> 
    /// <param name="sender">The sender of the event.</param> 
    /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
    private static void Visible_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     // TODO 
    } 

    /// <summary> 
    /// Function to handle a change to the <see cref="IsEnabledProperty"/>. 
    /// </summary> 
    /// <param name="sender">The sender of the event.</param> 
    /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
    private static void Enabled_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     // TODO 
    } 

    /// <summary> 
    /// When implemented in a derived class, creates a new instance of the <see cref="T:System.Windows.Freezable" /> derived class. 
    /// </summary> 
    /// <returns>The new instance.</returns> 
    protected Freezable CreateInstanceCore() 
    { 
     return new MyOldToolBarButton(); 
    } 
    #endregion 

    #region Constructor/Finalizer. 
    /// <summary> 
    /// Initializes a new instance of the <see cref="MyOldToolBarButton"/> class. 
    /// </summary> 
    /// <param name="buttonID">The ID of the button being clicked.</param> 
    /// <param name="defaultImageSource">The default image source URI for the glyph used by the button.</param> 
    internal void MyOldToolBarButton(string buttonID, string defaultImageSource) 
    { 
     ID = buttonID; 
     IsVisible = true; 
     IsEnabled = true; 
     ToolTip = string.Empty; 

     if (!string.IsNullOrWhiteSpace(defaultImageSource)) 
     { 
      _defaultImageSource = new Uri(defaultImageSource, UriKind.Relative); 
     } 
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="MyOldToolBarButton"/> class. 
    /// </summary> 
    public void MyOldToolBarButton() 
    { 
     // This is here to keep the XAML designer from complaining.   
    } 
    #endregion 
} 

并将其添加到另一个“父母”控制...的属性是这样的:

Properties

这是你在找什么?

+0

不完全。我想要的是将这些属性显示在“FullExtents”属性下的“MyToolbar”中。 我能够做到这一点,如果我用“新建”按钮创建按钮的新实例,但是当我在工具栏构造函数中创建FullExtents按钮的实例时,我得到我前面提到的结果。 基本上,该按钮应显示为“MyToolbar”UserControl上的属性,屏幕截图中的这些属性应显示在其下面。 – Mike

+0

为了更好地说明我的问题,我上传了一张显示主帖子中完整属性窗格的新照片。希望这将有助于消除我的帖子中的任何混淆。 – Mike