Существует ли способ сделать работу привязки C# статически?

Оказывается, что сброс YUI, CSS разделяет стиль списка от 'лития ул.' вместо просто 'ул.', которая является, почему установка его только на 'ул.' никогда не работала.

6
задан Scott Langham 23 September 2009 в 15:21
поделиться

4 ответа

Вы можете использовать выражения для получения проверенных компилятором привязок. Например, в одном из текущих проектов мы настроили привязки следующим образом:

DataBinder
    .BindToObject(this)
    .ObjectProperty(c => c.IsReadOnly)
        .Control(nameTextBox, n => n.ReadOnly)
        .Control(addressControl, n => n.ReadOnly)

Код, поддерживающий этот стиль, разделен на несколько классов:

public static class DataBinder
{
    public static DataBinderBindingSourceContext<TDataSource> BindToObject<TDataSource>(TDataSource dataSource)
    {
        return new DataBinderBindingSourceContext<TDataSource>(dataSource);
    }
}

public class DataBinderBindingSourceContext<TDataSource> 
{
    public readonly object DataSource;

    public DataBinderBindingSourceContext(object dataSource)
    {
        DataSource = dataSource;
    }

    public DataBinderControlContext<TDataSource, TProperty> ObjectProperty<TProperty>(Expression<Func<TDataSource, TProperty>> property)
    {
        return new DataBinderControlContext<TDataSource, TProperty>(this, property);
    }
}

public class DataBinderControlContext<TDataSource, TProperty>
{
    readonly DataBinderBindingSourceContext<TDataSource> BindingSourceContext;
    readonly string ObjectProperty;

    public DataBinderControlContext
        (
            DataBinderBindingSourceContext<TDataSource> bindingSourceContext,
            Expression<Func<TDataSource, TProperty>> objectProperty
        )
    {
        BindingSourceContext = RequireArg.NotNull(bindingSourceContext);
        ObjectProperty = ExpressionHelper.GetPropertyName(objectProperty);
    }

    public DataBinderControlContext<TDataSource, TProperty> Control<TControl>(TControl control, Expression<Func<TControl, TProperty>> property)
        where TControl : Control
    {
        var controlPropertyName = ExpressionHelper.GetPropertyName(property);
        control.DataBindings.Add(controlPropertyName, BindingSourceContext.DataSource, ObjectProperty, true);

        return this;
    }
}

public static class ExpressionHelper
{
    public static string GetPropertyName<TResult>(Expression<Func<TResult>> property)
    {
        return GetMemberNames(((LambdaExpression)property).Body).Skip(1).Join(".");
    }

    public static string GetPropertyName<T, TResult>(Expression<Func<T, TResult>> property)
    {
        return GetMemberNames(((LambdaExpression)property).Body).Join(".");
    }

    static IEnumerable<string> GetMemberNames(Expression expression)
    {
        if (expression is ConstantExpression || expression is ParameterExpression)
            yield break;

        var memberExpression = (MemberExpression)expression;

        foreach (var memberName in GetMemberNames(memberExpression.Expression))
            yield return memberName;

        yield return memberExpression.Member.Name;
    }
}

public static class StringExtentions
{
    public static string Join(this IEnumerable<string> values, string separator)
    {
        if (values == null)
            return null;

        return string.Join(separator, values.ToArray());
    }
}
2
ответ дан 10 December 2019 в 00:41
поделиться

Взгляните на этот фрагмент кода , который я разместил в другом вопросе, он может вам помочь! (Но только если вы используете .NET 3.5)

С уважением
Оливер Ханаппи

4
ответ дан 10 December 2019 в 00:41
поделиться

Вы можете сделать это с помощью деревьев выражений, как объяснено в этом вопросе

protected static string GetPropertyName<TSource, TResult>(Expression<Func<TSource, TResult>> expression)
{
    if (expression.NodeType == ExpressionType.Lambda && expression.Body.NodeType == ExpressionType.MemberAccess)
    {
        PropertyInfo prop = (expression.Body as MemberExpression).Member as PropertyInfo;
        if (prop != null)
        {
            return prop.Name;
        }
    }
    throw new ArgumentException("expression", "Not a property expression");
}

...

ageControl.Bind(p, GetPropertyName((Person p) => p.Age));
4
ответ дан 10 December 2019 в 00:41
поделиться

Вы можете использовать отражение, чтобы найти имя; - )

Это, конечно, будет циклическая ссылка, вы бы использовали имя, которое, по вашему мнению, должно быть, чтобы найти то же имя (или чтобы ничего не найти, то есть свойство было переименовано ... Но есть идея (или скорее, уловка): сделав бездействующую ссылку на свойство, которое вы хотите использовать, вы получите подтверждение во время компиляции, что оно все еще существует.Проблема только в том, что кто-то просто меняет местами различные имена свойств;

0
ответ дан 10 December 2019 в 00:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: