Потому что этот метод рендеринга - static
. По определению методы static
не могут получить доступ к переменной экземпляра. Вы должны удалить этот модификатор, если это возможно, и он должен работать.
По-видимому, e.Value.ToString () снова вызывает событие CellFormatting. Это кажется несколько логичным. Это должно быть достаточно легко выяснить с помощью отладчика.
Но реальная рекурсия может быть вызвана где-то еще, например, в форматировании по столбцам, которое вы пропустили.
Ваша рекурсивная проверка не является надежной, поскольку Value == null также сбрасывает ее, и она, по-видимому, используется всеми столбцами. Заставьте его окружать e.Value.ToString () более плотно:
if (e.Value != null)
{
cellFormatCallCount++;
System.Diagnostics.Debug.Assert(cellFormatCallCount <= 1, "Recursion");
value = e.Value.ToString();
cellFormatCallCount--;
...
}
Учитывая, что это событие, может ли оно вызывать себя?
Полностью случайное предположение (без трассировки стека это все, что я могу сделать) ...
Вы пытаетесь отобразить / отформатировать тип, который имеет потенциально рекурсивный ToString ()
?
public string ToString()
{
return ... this.ToString() ...
// or
return String.Format("The value is {0}", this);
}
Опечатка / ошибка, подобная этой, может вызвать StackOverflowException
...
Это не связано с проблемой, но на самом деле вы можете иметь StackOverflowException
вообще без рекурсии только с:
throw new StackOverflowException();
@Daniel: Если бы это было проблемой, разве это не вызвало бы исключение в строке:
if (e.Value != null) {
@gnirts: Не могли бы вы опубликовать полный метод и трассировку стека?
@BCS (ниже): Я думаю, что это может быть, но это может быть легко в некотором коде, который не показан в опубликованном демо.
PS. Извините, это должен был быть комментарий, но у меня недостаточно повторений :-D
Попробуйте сделать статическую переменную cellFormatCallCount, чтобы она использовалась всеми экземплярами класса. Я подозреваю, что событие как-то срабатывает само по себе, но вы его не видите, потому что cellFormatCallCount является локальным для каждого экземпляра класса, обрабатывающего событие, и, следовательно, никогда не увеличивается на единицу больше 1. Если это так, то фактический триггер для стекового потока (рекурсия) может быть где угодно в методе, и в этой строке просто не хватает места в стеке.
После того, как вы сделали переменную статической, вы можете вызвать исключение, когда оно превышает определенное (маленькое) значение, как 2. Это исключение должно оставить видимую трассировку стека.