возникла задача немного изменить стандартный ScrollView.
а именно поиметь в нём не один а два ScrollContentPresenter.
при этом поведение первого должно соответствовать оригиналу(скролиться по обеим осям), а второй только по горизонтали.
набросал такой шаблон
[TemplatePart(Name = "PART_EXScrollContentPresenter", Type = typeof(ScrollContentPresenter))]
public class ScrollViewerEX : ScrollViewer
{
//private ScrollContentPresenter timeLineContentPresenter = null;private ScrollContentPresenter timeScaleContentPresenter = null;
static ScrollViewerEX()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollViewerEX), new FrameworkPropertyMetadata(typeof(ScrollViewerEX)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
//this.timeLineContentPresenter = base.GetTemplateChild("PART_ScrollContentPresenter") as ScrollContentPresenter;this.timeScaleContentPresenter = base.GetTemplateChild("PART_EXScrollContentPresenter") as ScrollContentPresenter;
}
/*
protected override void OnScrollChanged(ScrollChangedEventArgs e)
{
base.OnScrollChanged(e);
if (e.HorizontalChange != 0)
{
if (this.timeScaleContentPresenter != null)
{
this.timeScaleContentPresenter.SetHorizontalOffset(e.HorizontalOffset);
}
}
}
*/
}
верхний ScrollContentPresenter работает как положено,а нижний не скролиться.
если раскоментировать OnScrollChanged? то всё заработает, но как то не кузяво на мой взгляд.
хотелось бы докопаться до правильного решения.
есть какие соображения? может кто знает как это сделано?
заранее спасибо.
Дык определите биндинг у PART_EXScrollContentPresenter. Посмотрите, как ScrollViewer стандартный с элементами шаблона работает. Cтандартный ScrollViewer ничего не знает о втором (вложенном) ScrollContentPresenter и не может им управлять.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, algama.
S>Дык определите биндинг у PART_EXScrollContentPresenter. Посмотрите, как ScrollViewer стандартный с элементами шаблона работает. Cтандартный ScrollViewer ничего не знает о втором (вложенном) ScrollContentPresenter и не может им управлять.
S>Никакой магии
дык... пытался... в коде ковырялся по самые уши но так и не вкурил... совсем уже запутался...
Здравствуйте, algama, Вы писали:
A>дык... пытался... в коде ковырялся по самые уши но так и не вкурил... совсем уже запутался...
А что не вкурил то? Всё правильно ответили. Стандартный ScrollViewer знать не знает про твой собственный Presenter, чего ж ты удивляешься. Даже больше скажу: мне кажется у тебя логическая ошибка. ScrollContentPresenter по смыслу спроектирован так, что он все-лишь элемент шаблона, строющий визуальное дерево по содержимому ScrollViewer. Ты же явно запихиваешь в него своё собственное содержимое, что противоречит целям использования данного элемента. Так что не серчай на WPF, что у нее не получается догадаться о твоей задаче
Можно рассмотреть другой вариант. Для второго содержимого (где кружочки всякие) использовать не ScrollContentPresenter, а Canvas. Элементам внутри Canvas сделать биндинг свойства Canvas.Left на текущую позицию PART_HorizontalScrollBar с конвертером, который будет инвертировать значение. Там, конечно, придется повозиться еще с размерами, но это всё-равно будет корректнее двух ScrollContentPresenter.
Ну или оставить вариант с обработчиком! В конце концов почему нет, в частном порядке
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, algama.
A>>дык... пытался... в коде ковырялся по самые уши но так и не вкурил... совсем уже запутался...
S>Тогда оставьте как есть и идите изучать матчасть, в WPF без этого тяжко.
Здравствуйте, MxKazan, Вы писали:
MK>Здравствуйте, algama, Вы писали:
A>>дык... пытался... в коде ковырялся по самые уши но так и не вкурил... совсем уже запутался... MK>А что не вкурил то? Всё правильно ответили. Стандартный ScrollViewer знать не знает про твой собственный Presenter, чего ж ты удивляешься. Даже больше скажу: мне кажется у тебя логическая ошибка. ScrollContentPresenter по смыслу спроектирован так, что он все-лишь элемент шаблона, строющий визуальное дерево по содержимому ScrollViewer. Ты же явно запихиваешь в него своё собственное содержимое, что противоречит целям использования данного элемента. Так что не серчай на WPF, что у нее не получается догадаться о твоей задаче MK>Можно рассмотреть другой вариант. Для второго содержимого (где кружочки всякие) использовать не ScrollContentPresenter, а Canvas. Элементам внутри Canvas сделать биндинг свойства Canvas.Left на текущую позицию PART_HorizontalScrollBar с конвертером, который будет инвертировать значение. Там, конечно, придется повозиться еще с размерами, но это всё-равно будет корректнее двух ScrollContentPresenter.
да я и не удивляюсь. прекрасно понимаю что ScrollViewer ничего не знает про второй ScrollContentPresenter. как то невзначай подумалось что можно забиндить необходимые свойства из первого на второй, но сам разобраться не смог вот и спросил у общественности.
С Canvas я начал, но получилось немного громоздко, вот и захотелось упростить.
MK>Ну или оставить вариант с обработчиком! В конце концов почему нет, в частном порядке
похоже так и оставлю... но некрасиво как то...
Здравствуйте, notacat, Вы писали:
N>а зачем именно ScrollViewer переопределять? N>Не проще сделать свой контрол, в который два ScrollViewer'а положить?
а смыл? зачем плодить сущности без надобности?
Здравствуйте, algama, Вы писали:
N>>а зачем именно ScrollViewer переопределять? N>>Не проще сделать свой контрол, в который два ScrollViewer'а положить? A>а смыл? зачем плодить сущности без надобности?
Да было бы чего плодить. Считай добавишь такой же ScrollContentPresenter, но с "человеческим лицом" По-моему, этот вариант даже удачнее Canvas'а.
Здравствуйте, MxKazan, Вы писали:
MK>Здравствуйте, algama, Вы писали:
N>>>а зачем именно ScrollViewer переопределять? N>>>Не проще сделать свой контрол, в который два ScrollViewer'а положить? A>>а смыл? зачем плодить сущности без надобности? MK>Да было бы чего плодить. Считай добавишь такой же ScrollContentPresenter, но с "человеческим лицом" По-моему, этот вариант даже удачнее Canvas'а.
мей би... подумаю...
всем спасибо, пошёл чесать репу и раскуривать бычок.
N>>а зачем именно ScrollViewer переопределять? N>>Не проще сделать свой контрол, в который два ScrollViewer'а положить? A>а смыл? зачем плодить сущности без надобности?
Почему плодить? Ну будет вместо SrollViewerEx контрол с другим названием и более простым темплейтом. Сущностей ровно столько же.