Назначение C# лямбда-функции в Aspx

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

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 ответа

Решение

Возможно, вы захотите вместо этого выставить свое свойство 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
        }
    }

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

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

public void GetCurrentRecords(object sender, EventArgs e)
{
    var obj  = sender as Lcmp.Website.Data.Controls.AFTO95ViewerControl;
    obj.ValidateMatrixFunc = whatever;
}

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

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

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

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

Другие вопросы по тегам