2016-06-14 34 views
0

Ich habe seit Tagen meinen Kopf gegen die Wand geschlagen, und ich kann keine Informationen finden, die zu meinem Problem passen.WPF-Button-Eigenschaft auf Benutzersteuerelement zeigt keine Eigenschaften im Eigenschaftsfenster an

Also, ich habe diese Symbolleiste Usercontrol, die in einer Anwendung abgelegt werden soll. Diese Symbolleiste verfügt über eine Eigenschaft, die als "FullExtentButton" bezeichnet wird, die einen Verweis auf die Schaltfläche darstellt. Ich möchte die Eigenschaften dieser Schaltfläche im Designer-Eigenschaftsbereich des Symbolleisten-Benutzersteuerelements verfügbar machen, damit die Entwickler die Eigenschaften direkt vom Designer festlegen können.

In WinForms war dies sehr einfach zu tun. WPF, nicht so sehr (außer ich bin nur blind).

In meinem Werkzeug Strichcode:

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

Dieser Wert im Konstruktor Steuerung der Benutzer festgelegt ist:

public MyToolbar() 
{ 
    InitializeComponent(); 

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

Der Knopf selbst ist recht einfach:

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 

Aber Wenn ich die button -Eigenschaft auf meinem Benutzersteuerelement im XAML-Designer anzeigen und seine Eigenschaften erweitern, bekomme ich Folgendes:

NoProperties

Wie Sie sehen können, gibt es keine Immobilien unter dieser Eigenschaft in der XAML-Designer. Ich möchte, dass die Eigenschaften für diese Schaltfläche unter der Eigenschaft "FullExtentsButton" erscheinen, damit meine Entwickler die Eigenschaften ändern können, aber nicht in der Lage sein müssen, die bereits vorhandene Instanz zu erstellen/entfernen.

Ich habe versucht, die FullExtentButton -Eigenschaft auf meinem UserControl eine DependencyProperty, aber das hat nichts behoben.

Dies ist Teil einer Standardsymbolleiste, die wir für verschiedene Anwendungen verwenden möchten. Daher ist es für uns sehr wichtig, Konsistenz zu gewährleisten. Außerdem können sich unsere Entwickler auf andere Teile der Anwendungen konzentrieren, anstatt immer wieder dasselbe zu implementieren (was wir gerade tun müssen).

Also, das sagte, ich bin bei meinem Verstand hier, was mache ich falsch?

+0

Die Art, wie ich dies tue ist, ich erstelle voll geblasene Benutzerkontrollen, die die kleinen Teile enthalten, wie MyToolBar Button ist ein Benutzersteuerelement anstelle eines Freezable. Dadurch können nicht nur Requisiten auf der Eigenschaftenseite angezeigt werden, Sie können das Steuerelement auch in jedes übergeordnete Steuerelement ziehen. In Ihrem Fall hätten Sie zwei Benutzerkontrollen: 1) MyToolBar und 2) MyToolBarButton, Ziehen Sie MyToolbarButton in MyToolbar und die Eigenschaften sollten angezeigt werden. –

+0

Das nenne ich Containment. "Favor composition over vererb" Sobald Sie dieses Konzept gewählt haben, ist es sehr cool! –

+0

Ich habe versucht mit dem UserControl, aber es hatte das gleiche Ergebnis. Der Zweck davon ist, die Schaltfläche zu einem permanenten Teil der Symbolleiste zu machen, dh der Benutzer darf sie nicht hinzufügen oder entfernen. Dies ist eine Standard-Symbolleiste, die eingefügt wird und Befehle an die Standardschaltflächen, die an ein Ansichtsmodell gebunden sind. Wir machen das so, dass unsere Entwickler nicht extra Arbeit für sich selbst aufbringen müssen und die Zeit, die es braucht, um diese kleine Funktionalität zu nutzen (und es Konsistenz für die Anwendungen bietet, in denen es verwendet wird). – Mike

Antwort

0

diesen Code verwenden, die ich etwas ändern musste, um es zu kompilieren zu bekommen ....

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

und auf eine andere „Eltern“ Kontrolle Hinzufügen ... Die Eigenschaften wie folgt aussehen:

Properties

Ist das wonach Sie suchen?

+0

Nicht genau. Ich möchte, dass diese Eigenschaften in "MyToolbar" unter der Eigenschaft "FullExtents" angezeigt werden. Ich bin in der Lage, dies zu tun, wenn ich eine neue Instanz der Schaltfläche mit der Schaltfläche "Neu" erstellen, aber wenn ich die Instanz der Schaltfläche FullExtents in der Symbolleiste Konstruktor erstellen, bekomme ich das zuvor erwähnte Ergebnis. Grundsätzlich sollte die Schaltfläche als eine Eigenschaft auf dem "MyToolbar" UserControl angezeigt werden, und diese Eigenschaften in dem Screenshot sollten darunter angezeigt werden. – Mike

+0

Um mein Problem besser zu veranschaulichen, habe ich ein neues Bild mit dem vollständigen Eigenschaftenbereich im Hauptbeitrag hochgeladen. Hoffentlich wird dies helfen, Verwirrung von meinem Beitrag zu beseitigen. – Mike