From 700f7256816e5fb4983a7964137f4c24f748b173 Mon Sep 17 00:00:00 2001 From: Tris Shores <86677757+v-trisshores@users.noreply.github.com> Date: Thu, 21 Oct 2021 13:37:58 -0500 Subject: [PATCH] Add article, code projects, toc, and redirects (#1179) --- .openpublishing.redirection.json | 8 ++ .../how-to-register-an-attached-property.md | 33 +++++ .../csharp/App.xaml.cs | 11 ++ .../csharp/AssemblyInfo.cs | 10 ++ .../csharp/CodeSampleCsharp.csproj | 24 ++++ .../csharp/MainWindow.xaml | 3 + .../csharp/MainWindow.xaml.cs | 37 ++++++ .../csharp/Properties/Resources.Designer.cs | 63 +++++++++ .../csharp/Properties/Resources.resx | 120 ++++++++++++++++++ .../csharp/app.xaml | 9 ++ .../vb/Application.xaml | 9 ++ .../vb/Application.xaml.vb | 6 + .../vb/AssemblyInfo.vb | 11 ++ .../vb/CodeSampleVb.vbproj | 22 ++++ .../vb/MainWindow.xaml | 3 + .../vb/MainWindow.xaml.vb | 39 ++++++ dotnet-desktop-guide/net/wpf/toc.yml | 2 + redirects_generator/definitions.json | 5 + 18 files changed, 415 insertions(+) create mode 100644 dotnet-desktop-guide/net/wpf/properties/how-to-register-an-attached-property.md create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/App.xaml.cs create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/AssemblyInfo.cs create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/CodeSampleCsharp.csproj create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml.cs create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/Properties/Resources.Designer.cs create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/Properties/Resources.resx create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/app.xaml create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/Application.xaml create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/Application.xaml.vb create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/AssemblyInfo.vb create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/CodeSampleVb.vbproj create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/MainWindow.xaml create mode 100644 dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/MainWindow.xaml.vb diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index 89b3205..f71b9a8 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -488,6 +488,14 @@ { "source_path": "dotnet-desktop-guide/framework/wpf/properties/dependency-property-value-precedence.md", "redirect_url": "/dotnet/desktop/wpf/advanced/dependency-property-value-precedence?view=netframeworkdesktop-4.8" + }, + { + "source_path": "dotnet-desktop-guide/net/wpf/advanced/how-to-register-an-attached-property.md", + "redirect_url": "/dotnet/desktop/wpf/properties/how-to-register-an-attached-property?view=netdesktop-5.0" + }, + { + "source_path": "dotnet-desktop-guide/framework/wpf/properties/how-to-register-an-attached-property.md", + "redirect_url": "/dotnet/desktop/wpf/advanced/how-to-register-an-attached-property?view=netframeworkdesktop-4.8" } ] } diff --git a/dotnet-desktop-guide/net/wpf/properties/how-to-register-an-attached-property.md b/dotnet-desktop-guide/net/wpf/properties/how-to-register-an-attached-property.md new file mode 100644 index 0000000..94396cd --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/how-to-register-an-attached-property.md @@ -0,0 +1,33 @@ +--- +title: "How to register an attached property" +description: "Learn about the Windows Presentation Foundation (WPF) property system and how to register an attached property and provide public accessors." +ms.date: "10/15/2021" +dev_langs: + - "csharp" + - "vb" +helpviewer_keywords: + - "attached properties [WPF], registering" + - "registering attached properties [WPF]" +--- + + +# How to register an attached property (WPF .NET) + +This article describes how to register an attached property and provide public accessors that let you access the attached property through Extensible Application Markup Language (XAML) and code. Attached properties enable extra property/value pairs to be set on any XAML element, even though the element doesn't define those extra properties in its object model. The extra properties are globally accessible. Attached properties are typically defined as a specialized form of dependency property that doesn't have a conventional property wrapper. Most attached properties for Windows Presentation Foundation (WPF) types are also implemented as dependency properties. You can create dependency properties on any derived type. + +## Example + +The following example shows how to register an attached property as a dependency property, by using the method. The provider class has the option of specifying a default value in property metadata. For more information on property metadata, see [Property metadata for a new dependency property](/dotnet/desktop/wpf/advanced/custom-dependency-properties?view=netframeworkdesktop-4.8&preserve-view=true#property-metadata-for-a-new-dependency-property). In this example, the `HasFish` property has a value type, with its default value set to `false`. + +The provider class for an attached property must provide static get/set accessor methods that follow the naming convention `Get` and `Set`. The XAML reader uses the accessors to recognize the XAML attribute for the attached property and resolve its value to the appropriate type. These accessors are necessary even if an attached property isn't registered as a dependency property. + +:::code language="csharp" source="./snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml.cs" id="RegisterAttachedProperty"::: +:::code language="vb" source="./snippets/how-to-register-an-attached-property/vb/MainWindow.xaml.vb" id="RegisterAttachedProperty"::: + +## See also + +- +- [Attached properties overview](/dotnet/desktop/wpf/advanced/attached-properties-overview?view=netframeworkdesktop-4.8&preserve-view=true) +- [Dependency properties overview](dependency-properties-overview.md) +- [Custom dependency properties](/dotnet/desktop/wpf/advanced/custom-dependency-properties?view=netframeworkdesktop-4.8&preserve-view=true) +- [How-to topics](/dotnet/desktop/wpf/advanced/properties-how-to-topics?view=netframeworkdesktop-4.8&preserve-view=true) diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/App.xaml.cs b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/App.xaml.cs new file mode 100644 index 0000000..bdad66d --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/App.xaml.cs @@ -0,0 +1,11 @@ +using System.Windows; + +namespace CodeSampleCsharp +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/AssemblyInfo.cs b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/AssemblyInfo.cs new file mode 100644 index 0000000..8b5504e --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/CodeSampleCsharp.csproj b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/CodeSampleCsharp.csproj new file mode 100644 index 0000000..8824b2f --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/CodeSampleCsharp.csproj @@ -0,0 +1,24 @@ + + + + WinExe + net5.0-windows + true + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml new file mode 100644 index 0000000..744218c --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml @@ -0,0 +1,3 @@ + diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml.cs b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml.cs new file mode 100644 index 0000000..7c61da6 --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/MainWindow.xaml.cs @@ -0,0 +1,37 @@ +using System.Windows; +using System.Windows.Controls; + +namespace CodeSampleCsharp +{ + /// + /// Interaction logic for MainWindow.xaml. + /// + public partial class MainWindow : Window + { + public MainWindow() => InitializeComponent(); + } + + // + public class Aquarium : DependencyObject + { + // Register an attached dependency property with the specified + // property name, property type, owner type, and property metadata. + public static readonly DependencyProperty HasFishProperty = + DependencyProperty.RegisterAttached( + "HasFish", + typeof(bool), + typeof(Aquarium), + new FrameworkPropertyMetadata(defaultValue: false, + flags: FrameworkPropertyMetadataOptions.AffectsRender) + ); + + // Declare a get accessor method. + public static bool GetHasFish(UIElement target) => + (bool)target.GetValue(HasFishProperty); + + // Declare a set accessor method. + public static void SetHasFish(UIElement target, bool value) => + target.SetValue(HasFishProperty, value); + } + // +} diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/Properties/Resources.Designer.cs b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/Properties/Resources.Designer.cs new file mode 100644 index 0000000..64552f9 --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace CodeSampleCsharp.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CodeSampleCsharp.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/Properties/Resources.resx b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/Properties/Resources.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/Properties/Resources.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/app.xaml b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/app.xaml new file mode 100644 index 0000000..867d2f0 --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/csharp/app.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/Application.xaml b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/Application.xaml new file mode 100644 index 0000000..f225972 --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/Application.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/Application.xaml.vb b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/Application.xaml.vb new file mode 100644 index 0000000..084cbe9 --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/Application.xaml.vb @@ -0,0 +1,6 @@ +Class Application + + ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException + ' can be handled in this file. + +End Class diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/AssemblyInfo.vb b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/AssemblyInfo.vb new file mode 100644 index 0000000..025ee72 --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/AssemblyInfo.vb @@ -0,0 +1,11 @@ +Imports System.Windows + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/CodeSampleVb.vbproj b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/CodeSampleVb.vbproj new file mode 100644 index 0000000..c7ae1cc --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/CodeSampleVb.vbproj @@ -0,0 +1,22 @@ + + + + WinExe + net5.0-windows + CodeSampleVb + true + + + + + + + + + + + + + + + diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/MainWindow.xaml b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/MainWindow.xaml new file mode 100644 index 0000000..85e5cee --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/MainWindow.xaml @@ -0,0 +1,3 @@ + diff --git a/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/MainWindow.xaml.vb b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/MainWindow.xaml.vb new file mode 100644 index 0000000..b1b3e45 --- /dev/null +++ b/dotnet-desktop-guide/net/wpf/properties/snippets/how-to-register-an-attached-property/vb/MainWindow.xaml.vb @@ -0,0 +1,39 @@ +Namespace CodeSampleVb + + ' + ' Interaction logic for MainWindow.xaml. + ' + Partial Public Class MainWindow + Inherits Window + + Public Sub New() + InitializeComponent() + End Sub + + End Class + + ' + Public Class Aquarium + Inherits DependencyObject + + ' Register an attached dependency property with the specified + ' property name, property type, owner type, and property metadata. + Public Shared ReadOnly HasFishProperty As DependencyProperty = + DependencyProperty.RegisterAttached("HasFish", GetType(Boolean), GetType(Aquarium), + New FrameworkPropertyMetadata(defaultValue:=False, + flags:=FrameworkPropertyMetadataOptions.AffectsRender)) + + ' Declare a get accessor method. + Public Shared Function GetHasFish(target As UIElement) As Boolean + Return target.GetValue(HasFishProperty) + End Function + + ' Declare a set accessor method. + Public Shared Sub SetHasFish(target As UIElement, value As Boolean) + target.SetValue(HasFishProperty, value) + End Sub + + End Class + ' + +End Namespace diff --git a/dotnet-desktop-guide/net/wpf/toc.yml b/dotnet-desktop-guide/net/wpf/toc.yml index 15597dd..86cf216 100644 --- a/dotnet-desktop-guide/net/wpf/toc.yml +++ b/dotnet-desktop-guide/net/wpf/toc.yml @@ -84,6 +84,8 @@ items: href: properties/dependency-properties-overview.md - name: Dependency property value precedence href: properties/dependency-property-value-precedence.md + - name: Register an attached property + href: properties/how-to-register-an-attached-property.md - name: Resources items: - name: Overview diff --git a/redirects_generator/definitions.json b/redirects_generator/definitions.json index a8e4b9c..083db02 100644 --- a/redirects_generator/definitions.json +++ b/redirects_generator/definitions.json @@ -329,6 +329,11 @@ "SourceUrl": "/dotnet/desktop/wpf/advanced/dependency-property-value-precedence?view=netframeworkdesktop-4.8", "TargetUrl": "/dotnet/desktop/wpf/properties/dependency-property-value-precedence?view=netdesktop-5.0" }, + { + "Redirect": "TwoWay", + "SourceUrl": "/dotnet/desktop/wpf/advanced/how-to-register-an-attached-property?view=netframeworkdesktop-4.8", + "TargetUrl": "/dotnet/desktop/wpf/properties/how-to-register-an-attached-property?view=netdesktop-5.0" + }, // Systems - XAML {