This is a migrated thread and some comments may be shown as answers.

using ExpressionEditor with Castle DictionaryAdpter

1 Answer 67 Views
ExpressionEditor
This is a migrated thread and some comments may be shown as answers.
Erhan
Top achievements
Rank 1
Erhan asked on 29 Sep 2016, 05:46 PM

If you find yourself binding your RadGridView to objects that are dynamically generated by Castle's DictionaryAdapter.

You might be surprised by the expressions that are generated by the ExpressionEditor involve a mysterious CastleDictionaryAdapterType like 

Expression {Expression<System.Func<CastleDictionaryAdapterType, bool>>}

when you were expecting it to be:

Expression {Expression<System.Func<IDataRecord, bool>>}

where IDataRecord is the interface your run-time instances are generated from by DictionaryAdapter

Despite the fact that CastleDictionaryAdapterType implements your IDataRecord (and a bunch of other things) you won't be able to directly cast between them as your FilterDescriptor requires

The solution is to re-write the expression that ExpressionEditor.Expression property gives you. Here's a simple expression visitor that does that:

public class CastleDictionaryAdapterTypeVisitor<TInput> : ExpressionVisitor
  {
    private ReadOnlyCollection<ParameterExpression> _parameters;
    private ParameterExpression _parameter;
 
    public Expression Modify(Expression expression_)
    {
      return Visit(expression_);
    }
 
    #region Overrides of ExpressionVisitor
    protected override Expression VisitParameter(ParameterExpression node_)
    {
      return _parameter ?? (_parameter = Expression.Parameter(typeof(TInput), node_.Name));
    }
 
    protected override Expression VisitLambda<T>(Expression<T> node_)
    {
      _parameters = VisitAndConvert(node_.Parameters, node_.Name);
      return Expression.Lambda(Visit(node_.Body), _parameters);
    }
 
    protected override Expression VisitMember(MemberExpression node_)
    {
      return node_.Member.DeclaringType?.ToString() == "CastleDictionaryAdapterType"
               ? Expression.Property(Visit(node_.Expression), node_.Member.Name) : base.VisitMember(node_);
    }
    #endregion
  }

 

You can use it like this (I've modified the ExpressionEditor filtering RadGridView Telerik sample) 

private void ExpressionEditor_OnExpressionChanged(object sender_, RadRoutedEventArgs e_)
{
 
  if(this.ExpressionEditor.Expression != null &&
    this.ExpressionEditor.Expression.GetType().ToString().Contains("CastleDictionaryAdapterType"))
  {
    var visitor = new CastleDictionaryAdapterTypeVisitor<ITestDataRecord>();
    var convertedExpression = visitor.Modify(ExpressionEditor.Expression) as Expression<Func<ITestDataRecord, bool>>;
 
    if (convertedExpression != null)
    this._genericFilterDescriptor.FilteringExpression = convertedExpression;
 
    if(!this.RadGridView.FilterDescriptors.Contains(this._genericFilterDescriptor))
      this.RadGridView.FilterDescriptors.Add(this._genericFilterDescriptor);
 
    this.errorMessageBlock.Visibility = Visibility.Collapsed;
  }
  else if(this.ExpressionEditor.Expression == null)
  {
    if(this.RadGridView.FilterDescriptors.Contains(this._genericFilterDescriptor))
      this.RadGridView.FilterDescriptors.Remove(this._genericFilterDescriptor);
 
    this.errorMessageBlock.Visibility = Visibility.Collapsed;
  }
  else
  {
    this.errorMessageBlock.Visibility = Visibility.Visible;
  }
}

What is needed here is to provide a way to signal to the ExpressionEditor the specific type/interface to use, as opposed to letting the control figure it out from its Item property.

 

 

 

 

 

1 Answer, 1 is accepted

Sort by
0
Martin
Telerik team
answered on 04 Oct 2016, 03:21 PM
Hello Erhan,

Thank you for sharing your solution with the community. We appreciate it. For that reason, I have updated your Telerik points as a gratitude for your cooperation. 

Regards,
Martin Vatev
Telerik by Progress
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Tags
ExpressionEditor
Asked by
Erhan
Top achievements
Rank 1
Answers by
Martin
Telerik team
Share this question
or