Сохранение фокуса управления на спинах постов с помощью PostBackOptions.TrackFocus

Сохранение фокуса на задних почтовых отправлениях - очевидно трудная задача. Поиск в Google, вы найдете кучу людей, которые хотят того же, но все подключить его по-разному, и в основном, на заказ. Я хотел бы избежать пользовательской реализации, особенно если есть способ, который поддерживается в.NET. Только после некоторого очень глубокого поиска я наткнулся на PostBackOptions.TrackFocus, о котором тихо упоминалось в другом сообщении о переполнении стека. По данным MSDN:

Получает или задает значение, указывающее, должно ли событие обратной передачи вернуть страницу в текущую позицию прокрутки и вернуть фокус текущему элементу управления. "

Черт возьми, это поддерживается.NET 4? КЛАССНО. Но у нас есть масса пользовательских элементов управления. Как.NET знает, как установить фокус на элементе управления? Я понятия не имею. Просматривая документацию MSDN для System.Web.UI.Control, есть интересный метод:

public virtual void Focus()

"Используйте метод Focus, чтобы установить начальный фокус веб-страницы для элемента управления. Страница будет открыта в браузере с выбранным элементом управления".

Хорошо, ясно, что это невозможно. Но каков рекомендуемый способ сделать это? Возвращает пустоту. Нет примеров. Невозможно найти какие-либо примеры людей, переопределяющих этот метод в своих реализациях. Однако после его переопределения и выполнения не более чем выдачи исключения становится очевидным, что ASP.NET фокусируется не на элементе управления, который был сфокусирован до обратной отправки: он никогда не вызывается.

После тонны отладки с использованием Firebug я обнаружил, что включение PostBackOptions.TrackFocus работает! Иногда. Очевидно, что фокус элемента управления сохраняется только тогда, когда элемент управления вызывает метод JavaScript __doPostBack. Другие элементы управления, которые запускают PostBack (при нажатии Enter внутри элемента управления), вызывают WebForm_OnSubmit(), который не обновляет скрытое поле ASP __LASTFOCUS. __doPostBack вызывает WebForm_OnSubmit () после установки скрытых полей.

Вот где я сейчас застрял. Похоже, мне нужно получить все для вызова __doPostBack, несмотря ни на что. Там очень, очень мало документации по использованию TrackFocus. Так у кого-нибудь есть какие-нибудь советы здесь?

2 ответа

Я поддерживал фокус на постбэках с помощью метода, описанного в этой статье: (то есть: сохранять фокус в скрытом поле __LASTFOCUS на поле enter клиентской стороне для всех элементов управления)

http://www.codeproject.com/KB/aspnet/MainatinFocusASPNET.aspx

Если вы дошли до того, что на странице появился __LASTFOCUS, это даст вам большую часть оставшейся части пути...

Примечание. Было бы неплохо найти способ не допустить вздутие дополнительного javascript, например, __VIEWSTATE.

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

Вот что я только что сделал. Предполагая, что в вашем коде есть обработчик, который заботится о событии и имеет такую ​​подпись:

protected void myEventHandler(object sender, EventArgs e)

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

        ScriptManager.RegisterStartupScript((WebControl) sender, sender.GetType(), "RestoreFocusMethod", "document.getElementById(\"" + ((WebControl) sender).ClientID + "\").focus();", true);

простое использование метода Focus() элемента управления отправкой переместит страницу (если вы немного прокрутите страницу вниз), но это прекрасно работает. И если у вас есть определенные обработчики для вашего элемента управления, вы можете просто использовать сам элемент управления, а не преобразовывать отправителя в WebControl, например так:

    protected void CityListDropDown_SelectedIndexChanged(object sender, EventArgs e)
    {
        ...
        ScriptManager.RegisterStartupScript(CityListDropDown, CityListDropDown.GetType(), "CityDropDownRefocus", "document.getElementById(\"" + CityListDropDown.ClientID + "\").focus();", true);
    }
Другие вопросы по тегам