实现ITransformProvider的Move方法时触发UIA属性变更事件范围异常
I’ve run into this exact headache while building UI Automation providers—let’s break down the likely causes and fix this step by step.
Common Root Causes
This error almost always traces back to one of these issues with the BoundingRectangle values you’re passing to RaiseAutomationPropertyChangedEvent:
- Invalid rectangle values: UI Automation expects non-negative X/Y coordinates and positive Width/Height values. Negative dimensions or coordinates will immediately trigger this exception.
- Mismatched or identical values: If the old and new
Rectvalues are identical, or you pass a non-Rect type to the event, the system will reject the call. - Broken property implementation: Your
BoundingRectangleproperty isn’t returning the updated position after the move, so the event’s new value doesn’t match what the provider reports. - Threading violation: You’re triggering the event from a non-UI thread, which violates UI Automation’s thread requirements.
Step-by-Step Fixes
1. Validate the New Bounding Rectangle
First, make sure your move logic produces a valid Rect before even thinking about triggering the event:
public void Move(double x, double y) { Rect oldBoundingRectangle = BoundingRectangle; // Execute your move logic here—update your internal position storage // Example: _internalRect is your field tracking the element's current position _internalRect = new Rect(x, y, _internalRect.Width, _internalRect.Height); // Validate the new rectangle to catch bad values early if (_internalRect.X < 0 || _internalRect.Y < 0 || _internalRect.Width <= 0 || _internalRect.Height <= 0) { throw new InvalidOperationException("Move resulted in an invalid bounding rectangle"); } // Rest of your logic... }
2. Ensure Correct Event Invocation
Double-check that you’re passing the right parameters, and only trigger the event if the value actually changed:
if (AutomationInteropProvider.ClientsAreListening && !oldBoundingRectangle.Equals(_internalRect)) { // Trigger the event on the UI thread if your Move method runs in a background thread Application.Current.Dispatcher.Invoke(() => { RaiseAutomationPropertyChangedEvent( AutomationElementIdentifiers.BoundingRectangleProperty, oldBoundingRectangle, _internalRect); }); }
- Always use
AutomationElementIdentifiers.BoundingRectanglePropertyas the property parameter. - Never pass
nullfor old/new values—both must be validRectinstances.
3. Verify Your BoundingRectangle Property
Ensure your BoundingRectangle property returns the updated value immediately after the move:
// If you're using a custom AutomationPeer public override Rect BoundingRectangle => _internalRect; // If implementing ITransformProvider directly, make sure the property getter uses your updated state
If this property still returns the old value when the event fires, UI Automation will detect a mismatch and throw the exception.
4. Check Threading
UI Automation events must be raised on the UI thread. If your Move method is called from a background thread, use the dispatcher to marshal the event call to the UI thread (as shown in the code above).
Additional Checks
- If your element is hidden or collapsed,
BoundingRectangleshould returnRect.Empty—but theMovemethod should only be called on visible elements, so ensure your provider correctly handles element visibility state. - Make sure you’re calling
RaiseAutomationPropertyChangedEventfrom the correctAutomationPeerinstance (your custom peer for the element being moved).
内容的提问来源于stack exchange,提问作者ForgetfulChimp

