Назначение C # лямбда-функции в Aspx - PullRequest
3 голосов
/ 13 октября 2011

У меня есть пользовательский элемент управления, где я хочу представить метод в качестве свойства (например, для пользовательской проверки);

public Func<bool> ValidateMatrixFunc { get; set; }

затем на странице, содержащей этот пользовательский элемент управления, я могу использовать делегат или лямбда-выражение для назначения события OnPreInit страницы;

 protected override void OnPreInit(EventArgs e)
 {
    base.OnPreInit(e);

    ucMatrixTable.ValidateMatrixFunc = ValidateMatrix;
 }

и это работает.

Однако, я думаю, было бы удобнее сделать это в aspx, например:

<uc1:MatrixTable ID="ucMatrixTable" runat="server" ValidateMatrixFunc="ValidateMatrix" />

Но это вылетает со следующим сообщением:

Невозможно создать объект типа 'System.Func`1 [[System.Boolean, mscorlib, Версия = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089]]' из строкового представления ValidateMatrix для свойство ValidateMatrixFunc.

Итак, мне просто интересно ... и мне интересно ... знает ли какой-нибудь ниндзя ответ на этот вопрос, или это лишь одна из тех загадок жизни, которую мы никогда не узнаем.

Ответы [ 4 ]

2 голосов
/ 18 ноября 2011

Возможно, вы захотите вместо этого выставить свое свойство ValidateMatrixFunc как событие.Зачем?это больше соответствует тому, как обычно реализованы элементы управления.Кроме того, события позволяют иметь несколько подписчиков (обработчиков событий) для одного события.Хотя это может быть и не типичный вариант использования, но иногда это происходит.

Ниже я описал, как реализовать это как событие:

Давайте назовем событие «ValidatingMatrix».

Тогда вы можете написать свою разметку ASPX следующим образом:

<uc1:MatrixTable ID="ucMatrixTable" runat="server" OnValidatingMatrix="ValidateMatrix" />

Кроме того, давайте использовать делегат CancelEventHandler вместо Func<bool>.Это означает, что ваша подпись метода ValidateMatrix в вашем коде должна выглядеть следующим образом:

protected void ValidateMatrix(object sender, System.ComponentModel.CancelEventArgs e)
{
    // perform validation logic

    if (validationFailed)
    {
        e.Cancel = true;
    }
}

Внутри вашего пользовательского элемента управления MatrixTable реализуйте что-то вроде этого:

    const string ValidatingMatrixEventKey = "ValidatingMatrix";

    public event System.ComponentModel.CancelEventHandler ValidatingMatrix
    {
        add { this.Events.AddHandler(ValidatingMatrixEventKey, value); }
        remove { this.Events.RemoveHandler(ValidatingMatrixEventKey, value); }
    }

    protected bool OnValidatingMatrix()
    {
        var handler = this.Events[ValidatingMatrixEventKey] as System.ComponentModel.CancelEventHandler;
        if (handler != null)
        {
            // prepare event args
            var e = new System.ComponentModel.CancelEventArgs(false);

            // call the event handlers (an event can have multiple event handlers)
            handler(this, e);

            // if any event handler changed the Cancel property to true, then validation failed (return false)
            return !e.Cancel;
        }

        // there were no event handlers, so validation passes by default (return true)
        return true;
    }

    private void MyLogic()
    {
        if (this.OnValidatingMatrix())
        {
            // validation passed
        }
        else
        {
            // validation failed
        }
    }
1 голос
/ 13 октября 2011

ASP.NET использует TypeConverters для преобразования string представления значения свойства, назначенного с помощью разметки, для преобразования string в правильный тип свойства. Ошибка говорит вам, что нет зарегистрированного TypeConverter для типа Func. TypeConverter должен быть зарегистрирован в самом классе, так что это не то, что вы могли бы сделать, и в любом случае я не думаю, что это позволит вам в любом случае достичь того, чего вы хотите.

1 голос
/ 18 ноября 2011

Этот подход не работает, но ваша основная цель очень распространена: использовать EventHandlers вместо Funcs . См. Эту статью MSDN для получения дополнительной информации: http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx

Вместо этого ваш обработчик возврата должен быть реализован в обработчике событий:

public void GetCurrentRecords(object sender, EventArgs e)
{
    var obj  = sender as Lcmp.Website.Data.Controls.AFTO95ViewerControl;
    obj.ValidateMatrixFunc = whatever;
}
1 голос
/ 13 октября 2011

Интерпретирует имя функции как литерал. Попробуйте использовать выражение привязки данных http://msdn.microsoft.com/en-us/library/bda9bbfx(v=vs.71).aspx

Вам нужно будет поиграть с ним, но вот возможный пример:

<uc1:MatrixTable ID="ucMatrixTable" runat="server" ValidateMatrixFunc="<%# ValidateMatrix %>" />
...