using System.ComponentModel.DataAnnotations.Resources; using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace System.ComponentModel.DataAnnotations { /// /// DisplayAttribute is a general-purpose attribute to specify user-visible globalizable strings for types and members. /// The string properties of this class can be used either as literals or as resource identifiers into a specified /// /// [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Method, AllowMultiple = false)] public sealed class DisplayAttribute : Attribute { #region Member Fields private Type _resourceType; private LocalizableString _shortName = new LocalizableString("ShortName"); private LocalizableString _name = new LocalizableString("Name"); private LocalizableString _description = new LocalizableString("Description"); private LocalizableString _prompt = new LocalizableString("Prompt"); private LocalizableString _groupName = new LocalizableString("GroupName"); private bool? _autoGenerateField; private bool? _autoGenerateFilter; private int? _order; #endregion #region All Constructors /// /// Default constructor for DisplayAttribute. All associated string properties and methods will return null. /// public DisplayAttribute() { } #endregion #region Properties /// /// Gets or sets the ShortName attribute property, which may be a resource key string. /// /// Consumers must use the method to retrieve the UI display string. /// /// /// /// The property contains either the literal, non-localized string or the resource key /// to be used in conjunction with to configure a localized /// short name for display. /// /// The method will return either the literal, non-localized /// string or the localized string when has been specified. /// /// /// /// The short name is generally used as the grid column label for a UI element bound to the member /// bearing this attribute. A null or empty string is legal, and consumers must allow for that. /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The property and method are a matched pair")] public string ShortName { get { return this._shortName.Value; } set { if (this._shortName.Value != value) { this._shortName.Value = value; } } } /// /// Gets or sets the Name attribute property, which may be a resource key string. /// /// Consumers must use the method to retrieve the UI display string. /// /// /// /// The property contains either the literal, non-localized string or the resource key /// to be used in conjunction with to configure a localized /// name for display. /// /// The method will return either the literal, non-localized /// string or the localized string when has been specified. /// /// /// /// The name is generally used as the field label for a UI element bound to the member /// bearing this attribute. A null or empty string is legal, and consumers must allow for that. /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The property and method are a matched pair")] public string Name { get { return this._name.Value; } set { if (this._name.Value != value) { this._name.Value = value; } } } /// /// Gets or sets the Description attribute property, which may be a resource key string. /// /// Consumers must use the method to retrieve the UI display string. /// /// /// /// The property contains either the literal, non-localized string or the resource key /// to be used in conjunction with to configure a localized /// description for display. /// /// The method will return either the literal, non-localized /// string or the localized string when has been specified. /// /// /// /// Description is generally used as a tool tip or description a UI element bound to the member /// bearing this attribute. A null or empty string is legal, and consumers must allow for that. /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The property and method are a matched pair")] public string Description { get { return this._description.Value; } set { if (this._description.Value != value) { this._description.Value = value; } } } /// /// Gets or sets the Prompt attribute property, which may be a resource key string. /// /// Consumers must use the method to retrieve the UI display string. /// /// /// /// The property contains either the literal, non-localized string or the resource key /// to be used in conjunction with to configure a localized /// prompt for display. /// /// The method will return either the literal, non-localized /// string or the localized string when has been specified. /// /// /// /// A prompt is generally used as a prompt or watermark for a UI element bound to the member /// bearing this attribute. A null or empty string is legal, and consumers must allow for that. /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The property and method are a matched pair")] public string Prompt { get { return this._prompt.Value; } set { if (this._prompt.Value != value) { this._prompt.Value = value; } } } /// /// Gets or sets the GroupName attribute property, which may be a resource key string. /// /// Consumers must use the method to retrieve the UI display string. /// /// /// /// The property contains either the literal, non-localized string or the resource key /// to be used in conjunction with to configure a localized /// group name for display. /// /// The method will return either the literal, non-localized /// string or the localized string when has been specified. /// /// /// /// A group name is used for grouping fields into the UI. A null or empty string is legal, /// and consumers must allow for that. /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The property and method are a matched pair")] public string GroupName { get { return this._groupName.Value; } set { if (this._groupName.Value != value) { this._groupName.Value = value; } } } /// /// Gets or sets the that contains the resources for , /// , , , and . /// Using along with these Key properties, allows the , /// , , , and /// methods to return localized values. /// public Type ResourceType { get { return this._resourceType; } set { if (this._resourceType != value) { this._resourceType = value; this._shortName.ResourceType = value; this._name.ResourceType = value; this._description.ResourceType = value; this._prompt.ResourceType = value; this._groupName.ResourceType = value; } } } /// /// Gets or sets whether UI should be generated automatically to display this field. If this property is not /// set then the presentation layer will automatically determine whether UI should be generated. Setting this /// property allows an override of the default behavior of the presentation layer. /// /// Consumers must use the method to retrieve the value, as this property getter will throw /// an exception if the value has not been set. /// /// /// /// If the getter of this property is invoked when the value has not been explicitly set using the setter. /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The property and method are a matched pair")] public bool AutoGenerateField { get { if (!this._autoGenerateField.HasValue) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, DataAnnotationsResources.DisplayAttribute_PropertyNotSet, "AutoGenerateField", "GetAutoGenerateField")); } return this._autoGenerateField.Value; } set { this._autoGenerateField = value; } } /// /// Gets or sets whether UI should be generated automatically to display filtering for this field. If this property is not /// set then the presentation layer will automatically determine whether filtering UI should be generated. Setting this /// property allows an override of the default behavior of the presentation layer. /// /// Consumers must use the method to retrieve the value, as this property getter will throw /// an exception if the value has not been set. /// /// /// /// If the getter of this property is invoked when the value has not been explicitly set using the setter. /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The property and method are a matched pair")] public bool AutoGenerateFilter { get { if (!this._autoGenerateFilter.HasValue) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, DataAnnotationsResources.DisplayAttribute_PropertyNotSet, "AutoGenerateFilter", "GetAutoGenerateFilter")); } return this._autoGenerateFilter.Value; } set { this._autoGenerateFilter = value; } } /// /// Gets or sets the order in which this field should be displayed. If this property is not set then /// the presentation layer will automatically determine the order. Setting this property explicitly /// allows an override of the default behavior of the presentation layer. /// /// Consumers must use the method to retrieve the value, as this property getter will throw /// an exception if the value has not been set. /// /// /// /// If the getter of this property is invoked when the value has not been explicitly set using the setter. /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The property and method are a matched pair")] public int Order { get { if (!this._order.HasValue) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, DataAnnotationsResources.DisplayAttribute_PropertyNotSet, "Order", "GetOrder")); } return this._order.Value; } set { this._order = value; } } #endregion #region Methods /// /// Gets the UI display string for ShortName. /// /// This can be either a literal, non-localized string provided to or the /// localized string found when has been specified and /// represents a resource key within that resource type. /// /// /// /// When has not been specified, the value of /// will be returned. /// /// When has been specified and /// represents a resource key within that resource type, then the localized value will be returned. /// /// /// If is null, the value from will be returned. /// /// /// /// After setting both the property and the property, /// but a public static property with a name matching the value couldn't be found /// on the . /// [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method does work using a property of the same name")] public string GetShortName() { return this._shortName.GetLocalizableValue() ?? this.GetName(); } /// /// Gets the UI display string for Name. /// /// This can be either a literal, non-localized string provided to or the /// localized string found when has been specified and /// represents a resource key within that resource type. /// /// /// /// When has not been specified, the value of /// will be returned. /// /// When has been specified and /// represents a resource key within that resource type, then the localized value will be returned. /// /// /// Can return null and will not fall back onto other values, as it's more likely for the /// consumer to want to fall back onto the property name. /// /// /// /// After setting both the property and the property, /// but a public static property with a name matching the value couldn't be found /// on the . /// [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method does work using a property of the same name")] public string GetName() { return this._name.GetLocalizableValue(); } /// /// Gets the UI display string for Description. /// /// This can be either a literal, non-localized string provided to or the /// localized string found when has been specified and /// represents a resource key within that resource type. /// /// /// /// When has not been specified, the value of /// will be returned. /// /// When has been specified and /// represents a resource key within that resource type, then the localized value will be returned. /// /// /// /// After setting both the property and the property, /// but a public static property with a name matching the value couldn't be found /// on the . /// [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method does work using a property of the same name")] public string GetDescription() { return this._description.GetLocalizableValue(); } /// /// Gets the UI display string for Prompt. /// /// This can be either a literal, non-localized string provided to or the /// localized string found when has been specified and /// represents a resource key within that resource type. /// /// /// /// When has not been specified, the value of /// will be returned. /// /// When has been specified and /// represents a resource key within that resource type, then the localized value will be returned. /// /// /// /// After setting both the property and the property, /// but a public static property with a name matching the value couldn't be found /// on the . /// [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method does work using a property of the same name")] public string GetPrompt() { return this._prompt.GetLocalizableValue(); } /// /// Gets the UI display string for GroupName. /// /// This can be either a literal, non-localized string provided to or the /// localized string found when has been specified and /// represents a resource key within that resource type. /// /// /// /// When has not been specified, the value of /// will be returned. /// /// When has been specified and /// represents a resource key within that resource type, then the localized value will be returned. /// /// /// /// After setting both the property and the property, /// but a public static property with a name matching the value couldn't be found /// on the . /// [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method does work using a property of the same name")] public string GetGroupName() { return this._groupName.GetLocalizableValue(); } /// /// Gets the value of if it has been set, or null. /// /// /// When has been set returns the value of that property. /// /// When has not been set returns null. /// /// [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method does work using a property of the same name")] public bool? GetAutoGenerateField() { return this._autoGenerateField; } /// /// Gets the value of if it has been set, or null. /// /// /// When has been set returns the value of that property. /// /// When has not been set returns null. /// /// [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method does work using a property of the same name")] public bool? GetAutoGenerateFilter() { return this._autoGenerateFilter; } /// /// Gets the value of if it has been set, or null. /// /// /// When has been set returns the value of that property. /// /// When has not been set returns null. /// /// /// /// When an order is not specified, presentation layers should consider using the value /// of 10000. This value allows for explicitly-ordered fields to be displayed before /// and after the fields that don't specify an order. /// [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method does work using a property of the same name")] public int? GetOrder() { return this._order; } #endregion } }