Оба window.pageYOffset и document.documentElement.scrollTop возвращают одинаковый результат во всех случаях.
Да, window.pageYOffset не поддерживается ниже IE 9.
Метод scrollTop () также может быть использован для получения вертикальной позиции полосы прокрутки конкретного элемента.
Я согласен с ответом Рекса М , но я бы пошел еще дальше. Если вы используете шаблон MVC (или что-то подобное), представление делегирует нажатие кнопки контроллеру. Конечно, методы контроллеров могут быть вызваны из любого места в вашем классе - скажем, из вашего обратного вызова таймера.
Итак, вернемся к вашему исходному коду:
using System.Windows.Forms;
class MyForm : Form
{
private Timer myTimer;
private Button myButton;
private MyController myController;
public MyForm()
{
// ...
// Initialize the components, etc.
// ...
myTimer.Tick += new EventHandler( myTimer_Tick );
myButton.Click += new EventHandler( myButton_Click );
myTimer.Start();
}
private void myTimer_Tick( object sender, EventArgs eventArgs )
{
myTimer.Stop();
myController.SomeMethod()
}
private void myButton_Click( object sender, EventArgs eventArgs )
{
// All the stuff done here will likely be moved
// into MyController.SomeMethod()
myController.SomeMethod();
}
}
Одним из преимуществ использования MVC является отделение контроллера от представления. Контроллер теперь можно легко использовать для нескольких типов представлений, а выход из графического интерфейса пользователя проще поддерживать, поскольку он содержит очень мало логики приложения.
РЕДАКТИРОВАТЬ: Добавлено в ответ на комментарии OP
В фундаментальных принципах проектирования программного обеспечения говорится о взаимосвязи и согласованности. Важно отметить, что мы стремимся минимизировать взаимосвязь между компонентами при максимальной согласованности, так как это приводит к созданию более модульной и удобной в обслуживании системы. Такие шаблоны, как MVC, и принципалы, такие как Open / Closed Principal, основываются на этих основах, предоставляя разработчику более ощутимые шаблоны реализации.
Итак, любой, кто пишет код, как показано в исходном посте, не понимает основ проектирования программного обеспечения и должен значительно развить свои навыки. OP следует похвалить за определение этого «запаха кода» и попытку понять, почему он не совсем правильный.
Некоторые соответствующие ссылки:
myButton.PerformClick ()
, вероятно, немного лучше, если вам не нужно передавать аргументы событий. Иногда вам просто нужно смоделировать щелчок.
Но да, я согласен, что лучше перенести реальный код в другую функцию. Я предпочитаю, чтобы мои обработчики событий были очень простыми - просто подключите пользовательский интерфейс к логике, которая находится где-то в другом месте.
Затем вы можете переставить и перепроектировать свой пользовательский интерфейс, не беспокоясь о том, где находится логика.
Это определенно не "личное предпочтение". Существует четкий, хорошо понятный подход к написанию кода, который должен быть хорошо структурированным, поддерживаемым, повторно используемым и понятным. Каждый метод в вашем коде должен инкапсулировать одну часть многоразовой функциональности. Структура вашего кода должна быть такой:
void ButtonClickEventHandler(...)
{
UserData userData = //determine user data from event data
DoUserThing(userData);
}
void DoUserThing(UserData userData)
{
//do stuff
}
void SomeOtherMethod()
{
UserData userData = //get userdata from some other source
DoUserThing(userData);
}
(Это очень общий пример. В правильном приложении все должно быть разделено на разные классы по признаку .)
Этот код увеличивает вероятность проблем, если другой кодировщик работает с методом myButton_Click.
Что, если бы я пришел, чтобы настроить реализацию обработчика myButton.Click? Я мог бы предположить, что объект отправителя - это кнопка, и попытаться выполнить приведение:
Button b = (Button)sender;
Я не знаю, не читая остальную часть реализации класса, что я не всегда получаю кнопку в качестве отправителя.
Итак, моя точка зрения составляет: -1 для удобства обслуживания, так как нарушаются предположения о том, какие объекты будут передаваться как параметры myButton_Click.
Короткий ответ: зачем имитировать нажатие кнопки, вызывая обработчик напрямую? Если вы хотите связать оба метода с одним и тем же событием, вы просто подключите его. Обработчики событий являются многоадресными делегатами, что означает, что вы можете добавить более одного из них. Подключение события более одного раза совершенно приемлемо.
myTimer.Tick += myTimer_Tick;
myTimer.Tick += myButton_Click;
myButton.Click += myButton_Click;
Независимо от того, является ли это WTF, - это инженерный вызов, который мы не можем сделать из короткого фрагмента кода. Однако, судя по вашим комментариям, это пахнет WTF. Формы или любой пользовательский интерфейс никогда не должны обрабатывать бизнес-логику. Они должны быть осведомлены о бизнес-логике до некоторой степени (как при валидации), но они не инкапсулируют / не применяют логику сами.
Двигаясь дальше, следуя некоторым простым практикам, таким как базовый рефакторинг, и используя многоуровневую (n-уровневую ) подход к программному обеспечению займет у вас долгий путь, и по ходу вы поймете, что представленный вами код плохо пахнет.
В конце концов вы столкнетесь с некоторыми высокоуровневыми шаблонами, такими как MVC (модель-представление-контроллер) и MVP (модель-представление-презентатор), которые шаг за рамки простого наслоения. Если вы последуете им, вы получите хорошее разделение проблем.
Я согласен с принятым ответом, но сразу переходя к «Использовать MVC», вот код, который не иллюстрирует MVC, без объяснения, почему это небольшой культ карго. для меня.
Особенности событий в C # (и инфраструктура .Net в целом - это делегат, который является эквивалентом указателя на функцию в C / C ++. Метод, прикрепленный к самому событию, не особенным в любом случае и должен быть доступен из любого места.
Обновление: возможно, мне следовало быть более многословным, но я думал, что моего использования «следует» вместо «может» или «может» будет достаточно. Я утверждаю, что обработчики событий должны вызываться, когда требуются реализуемые ими функции, вместо того, чтобы они становились оболочками для методов, которые «выполняют свою работу». Чем меньше вызовов методов у вас в стеке, тем лучше вы будете, особенно с влияние на производительность обработки исключений .Net.