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