Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.86] |
|
Сообщ.
#1
,
|
|
|
Есть форма. На этой форме находится панель (pnl1). На этой панели лежит UserControl список, у которого есть ряд панелей. Одна из панелей (pnl2) содержит кучу userControl'ов (Qx, где x > 30), и должна эту кучу скроллировать. У нее стоят свойства AutoScroll и ScrollMargin.
Все контролы Q, наследники от одного базового UserControl: public partial class BaseQuestionCtrl : UserControl { public BaseQuestionCtrl() { InitializeComponent(); } public virtual string MessageText { get; set; } public virtual int Order { get; protected set; } public virtual string Topic{ get; set; } public virtual bool ShowTopic { get; set; } public virtual bool ShowOrder { get; set; } public virtual bool TestFilter(QuestionFilter filter) { return true; } public virtual bool SaveChanges() { return false; } public event EventHandler<CallbackCommandEventArgs> CallbackCommand; protected void DoCallbackCommandEvent(CallbackCommand command) { if (CallbackCommand != null) CallbackCommand(this, new CallbackCommandEventArgs(command)); } } Суть в том, что при выполнение некоторых действий с каждым контролом должно вызываться определенное действите, в частности панель 2 должна прокрутиться к следующему контролу. Это делается при помощи события и нужной команды. Типа так: public partial class QuestionCtrlComboBox : BaseQuestionCtrl { *** private void TxbCorrectiveActionGotFocus(object sender, EventArgs e) { DoCallbackCommandEvent(TaskChecklistReport.CallbackCommand.ShowKeyboard); } private void TxbCorrectiveActionLostFocus(object sender, EventArgs e) { DoCallbackCommandEvent(TaskChecklistReport.CallbackCommand.HideKeyboard); } private void BtnOkClick(object sender, EventArgs e) { DoCallbackCommandEvent(TaskChecklistReport.CallbackCommand.HideKeyboard); DoCallbackCommandEvent(TaskChecklistReport.CallbackCommand.GoToNextQuestion); } } На форме обработчик выглядит так: private void OnCallbackCommand(object sender, CallbackCommandEventArgs callbackCommandEventArgs) { var ctrl = (BaseQuestionCtrl)sender; switch (callbackCommandEventArgs.Command) { case CallbackCommand.ShowKeyboard: qlcQuestions.ScrollTo(ctrl); inputPanel.Enabled = true; break; case CallbackCommand.HideKeyboard: inputPanel.Enabled = false; break; case CallbackCommand.GoToNextQuestion: var nextCtrl = qlcQuestions.GetNextCtrl(ctrl); if (nextCtrl != null) qlcQuestions.ScrollTo(nextCtrl); break; default: throw new ArgumentOutOfRangeException(); } } Т.е. для команды скроллинга ищется нужный контрол, и передается в метод ScrollTo контролу списку, который содержит панель, которая должна скроллироваться. Нужный котрол ищется правильно. Метод ScrollTo выглядит так: public void ScrollTo(BaseQuestionCtrl ctrl) { pnlQuestions.AutoScrollPosition = new Point(0, ctrl.Top); } Т.е. просто панели устанавливается нужная позиция. Контролы в панель добавляются так: foreach (var questionCtrl in _filteredQuestionCtrls) { pnlQuestions.Controls.Add(questionCtrl); questionCtrl.ShowOrder = ShowOrderInQuestions; questionCtrl.ShowTopic = questionCtrl.Topic != topic; topic = questionCtrl.Topic; questionCtrl.BringToFront(); } Где _filteredQuestionCtrls просто список всех отображаемых на панели контролов. У этих контролов стоит Dock = Top. Визуально они в правильном порядки и если мышкой тянуть скролл или нажимать на кнопки скролла, то все работает нормально. Если же при выполнении кода срабатывает событие CallbackCommand то в методе ScrollTo у контрола свойство Top имеет не правильное значение. Ну т.е. оно то может и правильное, но не такое как мне надо. В чем может быть проблема??? Самое интересное, что когда скроллинг был на панели формы (pnl1), а контрол списка изменял свои размеры так, что бы вместить все вопросы, то программный скроллинг работал нормально. Но понадобилось перенести его в панель которая находится в контроле списка (pnl2). Уже не знаю даже чего придумать. |
Сообщ.
#2
,
|
|
|
Странно, но как оказалось, что после скроллинга, значения топов считаются непонятно от чего.
В общем, так все работает как надо: pnlQuestions.AutoScrollPosition = new Point(0, Math.Abs(pnlQuestions.AutoScrollPosition.Y) + y); |