| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq.Expressions;
- using System.Reflection;
- namespace Avalonia.Data.Core
- {
- class IndexerExpressionNode : IndexerNodeBase
- {
- private readonly ParameterExpression _parameter;
- private readonly IndexExpression _expression;
- private readonly Delegate _setDelegate;
- private readonly Delegate _getDelegate;
- private readonly Delegate _firstArgumentDelegate;
- public IndexerExpressionNode(IndexExpression expression)
- {
- _parameter = Expression.Parameter(expression.Object.Type);
- _expression = expression.Update(_parameter, expression.Arguments);
- _getDelegate = Expression.Lambda(_expression, _parameter).Compile();
- var valueParameter = Expression.Parameter(expression.Type);
- _setDelegate = Expression.Lambda(Expression.Assign(_expression, valueParameter), _parameter, valueParameter).Compile();
- _firstArgumentDelegate = Expression.Lambda(_expression.Arguments[0], _parameter).Compile();
- }
- public override Type PropertyType => _expression.Type;
- public override string Description => _expression.ToString();
- protected override bool SetTargetValueCore(object value, BindingPriority priority)
- {
- try
- {
- _setDelegate.DynamicInvoke(Target.Target, value);
- return true;
- }
- catch (Exception)
- {
- return false;
- }
- }
- protected override object GetValue(object target)
- {
- try
- {
- return _getDelegate.DynamicInvoke(target);
- }
- catch (TargetInvocationException e) when (e.InnerException is ArgumentOutOfRangeException
- || e.InnerException is IndexOutOfRangeException
- || e.InnerException is KeyNotFoundException)
- {
- return AvaloniaProperty.UnsetValue;
- }
- }
- protected override bool ShouldUpdate(object sender, PropertyChangedEventArgs e)
- {
- return _expression.Indexer == null || _expression.Indexer.Name == e.PropertyName;
- }
- protected override int? TryGetFirstArgumentAsInt() => _firstArgumentDelegate.DynamicInvoke(Target.Target) as int?;
- }
- }
|