File: System\Windows\Automation\PropertyCondition.cs
Web Access
Project: src\src\Microsoft.DotNet.Wpf\src\UIAutomation\UIAutomationClient\UIAutomationClient.csproj (UIAutomationClient)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Globalization;
using System.Windows.Automation;
using MS.Internal.Automation;
 
namespace System.Windows.Automation
{
    /// <summary>
    /// Flags that affect how a property value is compared in a PropertyCondition
    /// </summary>
    [Flags]
#if (INTERNAL_COMPILE)
    internal enum PropertyConditionFlags
#else
    public enum PropertyConditionFlags
#endif
    {
        ///<summary>Properties are to be compared using default options (eg. case-sensitive comparison for strings)</summary>
        None = 0x00,
        ///<summary>For string comparisons, specifies that a case-insensitive comparison should be used</summary>
        IgnoreCase = 0x01,
    }
 
 
    /// <summary>
    /// Condition that checks whether a property has the specified value
    /// </summary>
#if (INTERNAL_COMPILE)
    internal class PropertyCondition : Condition
#else
    public class PropertyCondition : Condition
#endif
    {
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------
 
        #region Constructors
 
        /// <summary>
        /// Constructor to create a condition that checks whether a property has the specified value
        /// </summary>
        /// <param name="property">The property to check</param>
        /// <param name="value">The value to check the property for</param>
        public PropertyCondition( AutomationProperty property, object value )
        {
            Init(property, value, PropertyConditionFlags.None);
        }
 
        /// <summary>
        /// Constructor to create a condition that checks whether a property has the specified value
        /// </summary>
        /// <param name="property">The property to check</param>
        /// <param name="value">The value to check the property for</param>
        /// <param name="flags">Flags that affect the comparison</param>
        public PropertyCondition( AutomationProperty property, object value, PropertyConditionFlags flags )
        {
            Init(property, value, flags);
        }
 
 
 
        #endregion Constructors
 
        //------------------------------------------------------
        //
        //  Public Properties
        //
        //------------------------------------------------------
 
        #region Public Properties
 
        /// <summary>
        /// Returns the property that this condition is checking for
        /// </summary>
        public AutomationProperty Property
        {
            get
            {
                return _property;
            }
        }
 
        /// <summary>
        /// Returns the value of the property that this condition is checking for
        /// </summary>
        public object Value
        {
            get
            {
                return _val;
            }
        }
 
        /// <summary>
        /// Returns the flags used in this property comparison
        /// </summary>
        public PropertyConditionFlags Flags
        {
            get
            {
                return _flags;
            }
        }
 
        #endregion Public Properties
 
 
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------
 
        #region Private Methods
 
        void Init(AutomationProperty property, object val, PropertyConditionFlags flags )
        {
            ArgumentNullException.ThrowIfNull(property);
 
            AutomationPropertyInfo info;
            if (!Schema.GetPropertyInfo(property, out info))
            {
                throw new ArgumentException(SR.UnsupportedProperty);
            }
 
            // Check type is appropriate: NotSupported is allowed against any property,
            // null is allowed for any reference type (ie not for value types), otherwise
            // type must be assignable from expected type.
            Type expectedType = info.Type;
            if (val != AutomationElement.NotSupported &&
                ((val == null && expectedType.IsValueType)
                || (val != null && !expectedType.IsAssignableFrom(val.GetType()))))
            {
                throw new ArgumentException(SR.Format(SR.PropertyConditionIncorrectType, property.ProgrammaticName, expectedType.Name));
            }
 
            if ((flags & PropertyConditionFlags.IgnoreCase) != 0)
            {
                Misc.ValidateArgument(val is string, nameof(SR.IgnoreCaseRequiresString));
            }
 
            // Some types are handled differently in managed vs unmanaged - handle those here...
            if (val is AutomationElement)
            {
                // If this is a comparison against a Raw/LogicalElement,
                // save the runtime ID instead of the element so that we
                // can take it cross-proc if needed.
                val = ((AutomationElement)val).GetRuntimeId();
            }
            else if (val is ControlType)
            {
                // If this is a control type, use the ID, not the CLR object
                val = ((ControlType)val).Id;
            }
            else if (val is Rect)
            {
                Rect rc = (Rect)val;
                val = new double[] { rc.Left, rc.Top, rc.Width, rc.Height };
            }
            else if (val is Point)
            {
                Point pt = (Point)val;
                val = new double[] { pt.X, pt.Y };
            }
            else if (val is CultureInfo)
            {
                val = ((CultureInfo)val).LCID;
            }
            else if (val is AutomationHeadingLevel)
            {
                AutomationHeadingLevel automationHeadingLevel = (AutomationHeadingLevel)(val);
                switch(automationHeadingLevel)
                {
                    case AutomationHeadingLevel.None:
                        val = HeadingLevel.None;
                        break;
                    case AutomationHeadingLevel.Level1:
                        val = HeadingLevel.Level1;
                        break;
                    case AutomationHeadingLevel.Level2:
                        val = HeadingLevel.Level2;
                        break;
                    case AutomationHeadingLevel.Level3:
                        val = HeadingLevel.Level3;
                        break;
                    case AutomationHeadingLevel.Level4:
                        val = HeadingLevel.Level4;
                        break;
                    case AutomationHeadingLevel.Level5:
                        val = HeadingLevel.Level5;
                        break;
                    case AutomationHeadingLevel.Level6:
                        val = HeadingLevel.Level6;
                        break;
                    case AutomationHeadingLevel.Level7:
                        val = HeadingLevel.Level7;
                        break;
                    case AutomationHeadingLevel.Level8:
                        val = HeadingLevel.Level8;
                        break;
                    case AutomationHeadingLevel.Level9:
                        val = HeadingLevel.Level9;
                        break;
                    default:
                        val = HeadingLevel.None;
                        break;
                }
            }
 
            _property = property;
            _val = val;
            _flags = flags;
            SetMarshalData(new UiaCoreApi.UiaPropertyCondition(_property.Id, _val, _flags));
        }
 
        #endregion Private Methods
 
        //------------------------------------------------------
        //
        //  Private Fields
        //
        //------------------------------------------------------
 
        #region Private Fields
 
        private AutomationProperty _property;
        private object _val;
        private PropertyConditionFlags _flags;
 
        #endregion Private Fields
    }
}