Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I följande exempel visas hur du visar platshållartext i en TextBox när den TextBox är tom. När TextBox innehåller text döljs platshållartexten. Platshållartext hjälper användarna att förstå vilken typ av indata som TextBox förväntar sig.
I den här artikeln lär du dig hur du:
- Skapa en bifogad egenskap för att ange platshållartexten.
- Skapa en dekoration för att visa platshållartexten.
- Lägg till den anslutna egenskapen i en TextBox kontroll.
Skapa en bifogad egenskap
Med anslutna egenskaper kan du lägga till värden i en kontroll. Du använder den här funktionen mycket i WPF, till exempel när du anger Grid.Row eller Panel.ZIndex egenskaper för en kontroll. För mer information, se översikten över bifogade egenskaper. I det här exemplet används bifogade egenskaper för att lägga till platshållartext i en TextBox.
Lägg till en ny klass i projektet med namnet
TextBoxHelperoch öppna den.Lägg till följande namnområden:
using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media;Imports System.Linq Imports System.Security.Cryptography Imports System.Windows Imports System.Windows.Controls Imports System.Windows.Documents Imports System.Windows.MediaSkapa en ny beroendeegenskap med namnet
Placeholder.Den här beroendeegenskapen använder egenskapen ändrad återanropsdelegat.
public static string GetPlaceholder(DependencyObject obj) => (string)obj.GetValue(PlaceholderProperty); public static void SetPlaceholder(DependencyObject obj, string value) => obj.SetValue(PlaceholderProperty, value); public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.RegisterAttached( "Placeholder", typeof(string), typeof(TextBoxHelper), new FrameworkPropertyMetadata( defaultValue: null, propertyChangedCallback: OnPlaceholderChanged) );Public Shared Function GetPlaceholder(obj As DependencyObject) As String Return obj.GetValue(PlaceholderProperty) End Function Public Shared Sub SetPlaceholder(obj As DependencyObject, value As String) obj.SetValue(PlaceholderProperty, value) End Sub Public Shared ReadOnly PlaceholderProperty As DependencyProperty = DependencyProperty.RegisterAttached( "Placeholder", GetType(String), GetType(TextBoxHelper), New FrameworkPropertyMetadata( defaultValue:=Nothing, propertyChangedCallback:=AddressOf OnPlaceholderChanged) )Skapa metoden
OnPlaceholderChangedför att integrera den anslutna egenskapen med enTextBox.private static void OnPlaceholderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is TextBox textBoxControl) { if (!textBoxControl.IsLoaded) { // Ensure that the events are not added multiple times textBoxControl.Loaded -= TextBoxControl_Loaded; textBoxControl.Loaded += TextBoxControl_Loaded; } textBoxControl.TextChanged -= TextBoxControl_TextChanged; textBoxControl.TextChanged += TextBoxControl_TextChanged; // If the adorner exists, invalidate it to draw the current text if (GetOrCreateAdorner(textBoxControl, out PlaceholderAdorner adorner)) adorner.InvalidateVisual(); } }Private Shared Sub OnPlaceholderChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs) Dim textBoxControl = TryCast(d, TextBox) If textBoxControl IsNot Nothing Then If Not textBoxControl.IsLoaded Then 'Ensure that the events are not added multiple times RemoveHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded AddHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded End If RemoveHandler textBoxControl.TextChanged, AddressOf TextBoxControl_TextChanged AddHandler textBoxControl.TextChanged, AddressOf TextBoxControl_TextChanged 'If the adorner exists, invalidate it to draw the current text Dim adorner As PlaceholderAdorner = Nothing If GetOrCreateAdorner(textBoxControl, adorner) Then adorner.InvalidateVisual() End If End If End SubDet finns två sätt som den här metoden anropas när det kopplade egenskapsvärdet ändras:
- När den anslutna egenskapen först läggs till i en
TextBoxanropas den här metoden. Den här åtgärden ger den bifogade egenskapen en möjlighet att integrera med kontrollens händelser. - När den här egenskapen ändras kan utsmyckningen ogiltigförklaras för att uppdatera den visuella platshållartexten.
Metoden
GetOrCreateAdornerskapas i nästa avsnitt.- När den anslutna egenskapen först läggs till i en
Skapa händelsehanterarna för
TextBox.private static void TextBoxControl_Loaded(object sender, RoutedEventArgs e) { if (sender is TextBox textBoxControl) { textBoxControl.Loaded -= TextBoxControl_Loaded; GetOrCreateAdorner(textBoxControl, out _); } } private static void TextBoxControl_TextChanged(object sender, TextChangedEventArgs e) { if (sender is TextBox textBoxControl && GetOrCreateAdorner(textBoxControl, out PlaceholderAdorner adorner)) { // Control has text. Hide the adorner. if (textBoxControl.Text.Length > 0) adorner.Visibility = Visibility.Hidden; // Control has no text. Show the adorner. else adorner.Visibility = Visibility.Visible; } }Private Shared Sub TextBoxControl_Loaded(sender As Object, e As RoutedEventArgs) Dim textBoxControl As TextBox = TryCast(sender, TextBox) If textBoxControl IsNot Nothing Then RemoveHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded GetOrCreateAdorner(textBoxControl, Nothing) End If End Sub Private Shared Sub TextBoxControl_TextChanged(sender As Object, e As TextChangedEventArgs) Dim textBoxControl As TextBox = TryCast(sender, TextBox) Dim adorner As PlaceholderAdorner = Nothing If textBoxControl IsNot Nothing AndAlso GetOrCreateAdorner(textBoxControl, adorner) Then If textBoxControl.Text.Length > 0 Then 'Control has text. Hide the adorner. adorner.Visibility = Visibility.Hidden Else 'Control has no text. Show the adorner. adorner.Visibility = Visibility.Visible End If End If End SubHändelsen Loaded hanteras så att utsmyckningen kan skapas när kontrollens mall har tillämpats. Hanteraren tar bort sig själv när händelsen har tagits upp och utsmyckningen har skapats.
Händelsen TextChanged hanteras för att säkerställa att prydnaden är dold eller visas beroende på om Text är inställt på ett värde.
Skapa en utsmyckning
Adorner är ett visuellt objekt som är bundet till en kontroll och återges i en AdornerLayer. För mer information, se Adorners-översikt.
TextBoxHelperÖppna klassen.Lägg till följande kod för att skapa
GetOrCreateAdornermetoden.private static bool GetOrCreateAdorner(TextBox textBoxControl, out PlaceholderAdorner adorner) { // Get the adorner layer AdornerLayer layer = AdornerLayer.GetAdornerLayer(textBoxControl); // If null, it doesn't exist or the control's template isn't loaded if (layer == null) { adorner = null; return false; } // Layer exists, try to find the adorner adorner = layer.GetAdorners(textBoxControl)?.OfType<PlaceholderAdorner>().FirstOrDefault(); // Adorner never added to control, so add it if (adorner == null) { adorner = new PlaceholderAdorner(textBoxControl); layer.Add(adorner); } return true; }Private Shared Function GetOrCreateAdorner(textBoxControl As TextBox, ByRef adorner As PlaceholderAdorner) As Boolean 'Get the adorner layer Dim layer As AdornerLayer = AdornerLayer.GetAdornerLayer(textBoxControl) 'If nothing, it doesn't exist or the control's template isn't loaded If layer Is Nothing Then adorner = Nothing Return False End If 'Layer exists, try to find the adorner adorner = layer.GetAdorners(textBoxControl)?.OfType(Of PlaceholderAdorner)().FirstOrDefault() 'Adorner never added to control, so add it If adorner Is Nothing Then adorner = New PlaceholderAdorner(textBoxControl) layer.Add(adorner) End If Return True End FunctionDen här metoden ger ett säkert sätt att antingen lägga till eller hämta Adorner. Utsmyckningar kräver extra säkerhet eftersom de läggs till i kontrollens AdornerLayer, som kanske inte finns. När en XAML-ansluten egenskap tillämpas på en kontroll, har kontrollens mall ännu inte tillämpats för att skapa det visuella trädet, så dekorskiktet finns inte. Utsmyckningsskiktet måste hämtas när kontrollen har lästs in. Dekorskiktet kanske också saknas om en mall som utelämnar dekorskiktet tillämpas på styrningen.
Lägg till en underordnad klass med namnet
PlaceholderAdorneriTextBoxHelperklassen.public class PlaceholderAdorner : Adorner { public PlaceholderAdorner(TextBox textBox) : base(textBox) { } protected override void OnRender(DrawingContext drawingContext) { TextBox textBoxControl = (TextBox)AdornedElement; string placeholderValue = TextBoxHelper.GetPlaceholder(textBoxControl); if (string.IsNullOrEmpty(placeholderValue)) return; // Create the formatted text object FormattedText text = new FormattedText( placeholderValue, System.Globalization.CultureInfo.CurrentCulture, textBoxControl.FlowDirection, new Typeface(textBoxControl.FontFamily, textBoxControl.FontStyle, textBoxControl.FontWeight, textBoxControl.FontStretch), textBoxControl.FontSize, SystemColors.InactiveCaptionBrush, VisualTreeHelper.GetDpi(textBoxControl).PixelsPerDip); text.MaxTextWidth = System.Math.Max(textBoxControl.ActualWidth - textBoxControl.Padding.Left - textBoxControl.Padding.Right, 10); text.MaxTextHeight = System.Math.Max(textBoxControl.ActualHeight, 10); // Render based on padding of the control, to try and match where the textbox places text Point renderingOffset = new Point(textBoxControl.Padding.Left, textBoxControl.Padding.Top); // Template contains the content part; adjust sizes to try and align the text if (textBoxControl.Template.FindName("PART_ContentHost", textBoxControl) is FrameworkElement part) { Point partPosition = part.TransformToAncestor(textBoxControl).Transform(new Point(0, 0)); renderingOffset.X += partPosition.X; renderingOffset.Y += partPosition.Y; text.MaxTextWidth = System.Math.Max(part.ActualWidth - renderingOffset.X, 10); text.MaxTextHeight = System.Math.Max(part.ActualHeight, 10); } // Draw the text drawingContext.DrawText(text, renderingOffset); } }Public Class PlaceholderAdorner Inherits Adorner Public Sub New(adornedElement As UIElement) MyBase.New(adornedElement) End Sub Protected Overrides Sub OnRender(drawingContext As DrawingContext) Dim textBoxControl As TextBox = DirectCast(AdornedElement, TextBox) Dim placeholderValue As String = TextBoxHelper.GetPlaceholder(textBoxControl) If String.IsNullOrEmpty(placeholderValue) Then Return End If 'Create the formatted text object Dim text As New FormattedText( placeholderValue, System.Globalization.CultureInfo.CurrentCulture, textBoxControl.FlowDirection, New Typeface(textBoxControl.FontFamily, textBoxControl.FontStyle, textBoxControl.FontWeight, textBoxControl.FontStretch), textBoxControl.FontSize, SystemColors.InactiveCaptionBrush, VisualTreeHelper.GetDpi(textBoxControl).PixelsPerDip) text.MaxTextWidth = Math.Max(textBoxControl.ActualWidth - textBoxControl.Padding.Left - textBoxControl.Padding.Right, 10) text.MaxTextHeight = Math.Max(textBoxControl.ActualHeight, 10) 'Render based on padding of the control, to try and match where the textbox places text Dim renderingOffset As New Point(textBoxControl.Padding.Left, textBoxControl.Padding.Top) 'Template contains the content part; adjust sizes to try and align the text Dim part As FrameworkElement = TryCast(textBoxControl.Template.FindName("PART_ContentHost", textBoxControl), FrameworkElement) If part IsNot Nothing Then Dim partPosition As Point = part.TransformToAncestor(textBoxControl).Transform(New Point(0, 0)) renderingOffset.X += partPosition.X renderingOffset.Y += partPosition.Y text.MaxTextWidth = Math.Max(part.ActualWidth - renderingOffset.X, 10) text.MaxTextHeight = Math.Max(part.ActualHeight, 10) End If ' Draw the text drawingContext.DrawText(text, renderingOffset) End Sub End ClassEn prydnad ärver från klassen Adorner. Den här utsmyckningen överrider OnRender(DrawingContext)-metoden för att rita platshållartexten. Låt oss bryta ner koden:
- Kontrollera först att platshållartexten finns genom att anropa
TextBoxHelper.GetPlaceholder(textBoxControl). - Skapa ett FormattedText objekt. Det här objektet innehåller all information om vilken text som ritas på det visuella.
- Både FormattedText.MaxTextWidth och FormattedText.MaxTextHeight egenskaperna är inställda på kontrollens region. De har också ett minimivärde på 10 för att se till att objektet
FormattedTextär giltigt. -
renderingOffsetlagrar positionen för den ritade texten. - Använd
PART_ContentHostom kontrollens mall deklarerar det. Den här delen representerar var texten ritas på kontrollens mall. Om den delen hittas ändrar durenderingOffsetför att ta hänsyn till dess position. - Rita texten genom att anropa DrawText(FormattedText, Point) och skicka
FormattedTextobjektet och textens position.
- Kontrollera först att platshållartexten finns genom att anropa
Använd den bifogade egenskapen
När den anslutna egenskapen har definierats måste dess namnområde importeras till XAML och sedan refereras till på en TextBox kontroll. Följande kod mappar .NET-namnområdet DotnetDocsSample till XML-namnområdet l.
<Window x:Class="DotnetDocsSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:DotnetDocsSample"
Title="Recipe Tracker" Width="400" SizeToContent="Height">
<StackPanel Margin="10">
<TextBlock FontSize="20" TextWrapping="Wrap">Welcome to Recipe Tracker! To get started, create a new account.</TextBlock>
<Label Padding="0,5">Name</Label>
<TextBox l:TextBoxHelper.Placeholder="Ex. Jeffry Goh" />
<Label Padding="0,5">Email</Label>
<TextBox l:TextBoxHelper.Placeholder="jeffry@contoso.com" />
<Label Padding="0,5">Password</Label>
<PasswordBox />
<Button HorizontalAlignment="Right" Width="100" Margin="0,10,0,5">Submit</Button>
</StackPanel>
</Window>
Den bifogade egenskapen läggs till i en TextBox med hjälp av syntaxen xmlNamespace:Class.Property.
Fullständigt exempel
Följande kod är den fullständiga TextBoxHelper klassen.
public static class TextBoxHelper
{
public static string GetPlaceholder(DependencyObject obj) =>
(string)obj.GetValue(PlaceholderProperty);
public static void SetPlaceholder(DependencyObject obj, string value) =>
obj.SetValue(PlaceholderProperty, value);
public static readonly DependencyProperty PlaceholderProperty =
DependencyProperty.RegisterAttached(
"Placeholder",
typeof(string),
typeof(TextBoxHelper),
new FrameworkPropertyMetadata(
defaultValue: null,
propertyChangedCallback: OnPlaceholderChanged)
);
private static void OnPlaceholderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBox textBoxControl)
{
if (!textBoxControl.IsLoaded)
{
// Ensure that the events are not added multiple times
textBoxControl.Loaded -= TextBoxControl_Loaded;
textBoxControl.Loaded += TextBoxControl_Loaded;
}
textBoxControl.TextChanged -= TextBoxControl_TextChanged;
textBoxControl.TextChanged += TextBoxControl_TextChanged;
// If the adorner exists, invalidate it to draw the current text
if (GetOrCreateAdorner(textBoxControl, out PlaceholderAdorner adorner))
adorner.InvalidateVisual();
}
}
private static void TextBoxControl_Loaded(object sender, RoutedEventArgs e)
{
if (sender is TextBox textBoxControl)
{
textBoxControl.Loaded -= TextBoxControl_Loaded;
GetOrCreateAdorner(textBoxControl, out _);
}
}
private static void TextBoxControl_TextChanged(object sender, TextChangedEventArgs e)
{
if (sender is TextBox textBoxControl
&& GetOrCreateAdorner(textBoxControl, out PlaceholderAdorner adorner))
{
// Control has text. Hide the adorner.
if (textBoxControl.Text.Length > 0)
adorner.Visibility = Visibility.Hidden;
// Control has no text. Show the adorner.
else
adorner.Visibility = Visibility.Visible;
}
}
private static bool GetOrCreateAdorner(TextBox textBoxControl, out PlaceholderAdorner adorner)
{
// Get the adorner layer
AdornerLayer layer = AdornerLayer.GetAdornerLayer(textBoxControl);
// If null, it doesn't exist or the control's template isn't loaded
if (layer == null)
{
adorner = null;
return false;
}
// Layer exists, try to find the adorner
adorner = layer.GetAdorners(textBoxControl)?.OfType<PlaceholderAdorner>().FirstOrDefault();
// Adorner never added to control, so add it
if (adorner == null)
{
adorner = new PlaceholderAdorner(textBoxControl);
layer.Add(adorner);
}
return true;
}
public class PlaceholderAdorner : Adorner
{
public PlaceholderAdorner(TextBox textBox) : base(textBox) { }
protected override void OnRender(DrawingContext drawingContext)
{
TextBox textBoxControl = (TextBox)AdornedElement;
string placeholderValue = TextBoxHelper.GetPlaceholder(textBoxControl);
if (string.IsNullOrEmpty(placeholderValue))
return;
// Create the formatted text object
FormattedText text = new FormattedText(
placeholderValue,
System.Globalization.CultureInfo.CurrentCulture,
textBoxControl.FlowDirection,
new Typeface(textBoxControl.FontFamily,
textBoxControl.FontStyle,
textBoxControl.FontWeight,
textBoxControl.FontStretch),
textBoxControl.FontSize,
SystemColors.InactiveCaptionBrush,
VisualTreeHelper.GetDpi(textBoxControl).PixelsPerDip);
text.MaxTextWidth = System.Math.Max(textBoxControl.ActualWidth - textBoxControl.Padding.Left - textBoxControl.Padding.Right, 10);
text.MaxTextHeight = System.Math.Max(textBoxControl.ActualHeight, 10);
// Render based on padding of the control, to try and match where the textbox places text
Point renderingOffset = new Point(textBoxControl.Padding.Left, textBoxControl.Padding.Top);
// Template contains the content part; adjust sizes to try and align the text
if (textBoxControl.Template.FindName("PART_ContentHost", textBoxControl) is FrameworkElement part)
{
Point partPosition = part.TransformToAncestor(textBoxControl).Transform(new Point(0, 0));
renderingOffset.X += partPosition.X;
renderingOffset.Y += partPosition.Y;
text.MaxTextWidth = System.Math.Max(part.ActualWidth - renderingOffset.X, 10);
text.MaxTextHeight = System.Math.Max(part.ActualHeight, 10);
}
// Draw the text
drawingContext.DrawText(text, renderingOffset);
}
}
}
Public Class TextBoxHelper
Public Shared Function GetPlaceholder(obj As DependencyObject) As String
Return obj.GetValue(PlaceholderProperty)
End Function
Public Shared Sub SetPlaceholder(obj As DependencyObject, value As String)
obj.SetValue(PlaceholderProperty, value)
End Sub
Public Shared ReadOnly PlaceholderProperty As DependencyProperty =
DependencyProperty.RegisterAttached(
"Placeholder",
GetType(String),
GetType(TextBoxHelper),
New FrameworkPropertyMetadata(
defaultValue:=Nothing,
propertyChangedCallback:=AddressOf OnPlaceholderChanged)
)
Private Shared Sub OnPlaceholderChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
Dim textBoxControl = TryCast(d, TextBox)
If textBoxControl IsNot Nothing Then
If Not textBoxControl.IsLoaded Then
'Ensure that the events are not added multiple times
RemoveHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded
AddHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded
End If
RemoveHandler textBoxControl.TextChanged, AddressOf TextBoxControl_TextChanged
AddHandler textBoxControl.TextChanged, AddressOf TextBoxControl_TextChanged
'If the adorner exists, invalidate it to draw the current text
Dim adorner As PlaceholderAdorner = Nothing
If GetOrCreateAdorner(textBoxControl, adorner) Then
adorner.InvalidateVisual()
End If
End If
End Sub
Private Shared Sub TextBoxControl_Loaded(sender As Object, e As RoutedEventArgs)
Dim textBoxControl As TextBox = TryCast(sender, TextBox)
If textBoxControl IsNot Nothing Then
RemoveHandler textBoxControl.Loaded, AddressOf TextBoxControl_Loaded
GetOrCreateAdorner(textBoxControl, Nothing)
End If
End Sub
Private Shared Sub TextBoxControl_TextChanged(sender As Object, e As TextChangedEventArgs)
Dim textBoxControl As TextBox = TryCast(sender, TextBox)
Dim adorner As PlaceholderAdorner = Nothing
If textBoxControl IsNot Nothing AndAlso GetOrCreateAdorner(textBoxControl, adorner) Then
If textBoxControl.Text.Length > 0 Then
'Control has text. Hide the adorner.
adorner.Visibility = Visibility.Hidden
Else
'Control has no text. Show the adorner.
adorner.Visibility = Visibility.Visible
End If
End If
End Sub
Private Shared Function GetOrCreateAdorner(textBoxControl As TextBox, ByRef adorner As PlaceholderAdorner) As Boolean
'Get the adorner layer
Dim layer As AdornerLayer = AdornerLayer.GetAdornerLayer(textBoxControl)
'If nothing, it doesn't exist or the control's template isn't loaded
If layer Is Nothing Then
adorner = Nothing
Return False
End If
'Layer exists, try to find the adorner
adorner = layer.GetAdorners(textBoxControl)?.OfType(Of PlaceholderAdorner)().FirstOrDefault()
'Adorner never added to control, so add it
If adorner Is Nothing Then
adorner = New PlaceholderAdorner(textBoxControl)
layer.Add(adorner)
End If
Return True
End Function
Public Class PlaceholderAdorner
Inherits Adorner
Public Sub New(adornedElement As UIElement)
MyBase.New(adornedElement)
End Sub
Protected Overrides Sub OnRender(drawingContext As DrawingContext)
Dim textBoxControl As TextBox = DirectCast(AdornedElement, TextBox)
Dim placeholderValue As String = TextBoxHelper.GetPlaceholder(textBoxControl)
If String.IsNullOrEmpty(placeholderValue) Then
Return
End If
'Create the formatted text object
Dim text As New FormattedText(
placeholderValue,
System.Globalization.CultureInfo.CurrentCulture,
textBoxControl.FlowDirection,
New Typeface(textBoxControl.FontFamily,
textBoxControl.FontStyle,
textBoxControl.FontWeight,
textBoxControl.FontStretch),
textBoxControl.FontSize,
SystemColors.InactiveCaptionBrush,
VisualTreeHelper.GetDpi(textBoxControl).PixelsPerDip)
text.MaxTextWidth = Math.Max(textBoxControl.ActualWidth - textBoxControl.Padding.Left - textBoxControl.Padding.Right, 10)
text.MaxTextHeight = Math.Max(textBoxControl.ActualHeight, 10)
'Render based on padding of the control, to try and match where the textbox places text
Dim renderingOffset As New Point(textBoxControl.Padding.Left, textBoxControl.Padding.Top)
'Template contains the content part; adjust sizes to try and align the text
Dim part As FrameworkElement = TryCast(textBoxControl.Template.FindName("PART_ContentHost", textBoxControl), FrameworkElement)
If part IsNot Nothing Then
Dim partPosition As Point = part.TransformToAncestor(textBoxControl).Transform(New Point(0, 0))
renderingOffset.X += partPosition.X
renderingOffset.Y += partPosition.Y
text.MaxTextWidth = Math.Max(part.ActualWidth - renderingOffset.X, 10)
text.MaxTextHeight = Math.Max(part.ActualHeight, 10)
End If
' Draw the text
drawingContext.DrawText(text, renderingOffset)
End Sub
End Class
End Class
Se även
- Textrutaöversikt
- Översikt över utsmyckningar
- Översikt över anslutna egenskaper
.NET Desktop feedback