Странное поведение Silverlight RichTextBox / ListBox / ScrollViewer

У меня есть пользовательский элемент управления со следующим XAML:

<ScrollViewer>
    <ListBox ItemsSource="{Binding Items}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <RichTextBox>
                    <Paragraph>
                        <Run Text="{Binding}"/>
                    </Paragraph>
                </RichTextBox>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</ScrollViewer>

И код позади:

public partial class MainPage {
    public MainPage() {
        InitializeComponent();
        Items = new ObservableCollection<string>(Enumerable.Range(0, 100).Select(x => "some text"));
        DataContext = this;
    }

    public ObservableCollection<string> Items { get; set; }
}

Когда этот код запускается, вертикальная полоса прокрутки ScrollViewer опускается вниз. Однако, если я удалю привязку в Run в RichTextBox и жестко закодирую текст:

<Run Text="some text"/>

Теперь полоса прокрутки остается вверху (как я и ожидал).

Это ошибка? Если нет, то что происходит? Как я могу это исправить (примечание: это упрощенный XAML, мне нужен ScrollViewer, потому что ListBox фактически находится в сетке)?


person JontyMC    schedule 04.10.2011    source источник
comment
Привет, это может быть глупо, но ListView может прокручивать свое содержимое без средства просмотра прокрутки - если вы вложите свой ListView непосредственно в сетку, он отобразит вертикальную полосу прокрутки и не будет прокручиваться вниз. Вы также можете захватить ItemsPanel.   -  person    schedule 06.10.2011
comment
Silverlight не имеет элемента управления ListView. Я подозреваю, что даже если бы он это сделал, он использовал бы ScrollViewer в шаблоне.   -  person JontyMC    schedule 11.10.2011
comment
Мне кажется, что это ошибка. Как бы то ни было, если вы замените RichTextBox на TextBlock (и оставите там {Binding}), средство просмотра прокрутки будет вести себя нормально и останется наверху. Таким образом, проблема проявляется в сочетании RichTextBox и связанного содержимого.   -  person Matt Bridges    schedule 12.10.2011
comment
Я также попытался избавиться от средства просмотра прокрутки и переопределить ItemsPanelTemplate с помощью StackPanel (вместо VirtualizingStackPanel), и результат был точно таким же - прокрутка вниз при привязке.   -  person Matt Bridges    schedule 12.10.2011


Ответы (6)


Я не могу сказать вам, почему ScrollViewer ведет себя так, но я бы изменил XAML на следующий. Затем вверху находится ползунок, если вы используете привязку или нет в DataTemplate.

XAML:

<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding Items}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <RichTextBox>
        <Paragraph>
          <Run Text="{Binding}"/>
        </Paragraph>
      </RichTextBox>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
person Jehof    schedule 07.10.2011
comment
Разве это не то, что я сказал в своем комментарии ?;) Еще один аргумент в пользу НЕ использования scrollviewer - это делает невозможным использование кнопки прокрутки мыши. - person ; 07.10.2011
comment
Мне нужно использовать ScrollViewer, потому что мне нужен дополнительный контент (заголовок списка) для прокрутки списка. Я также не могу использовать VirtualizingStackPanel, потому что мне нужна плавная прокрутка. - person JontyMC; 11.10.2011
comment
Вы можете сделать и то, и другое с ListView, просто переопределите ItemsPanel, чтобы настроить панель элементов на все, что вам нужно, включая. VirtualizingStackPanel :) Как я уже сказал, главный недостаток элементов управления хостингом в ScrollViewer - вы потеряете поддержку прокрутки мыши. - person ; 12.10.2011
comment
Я не понимаю, что вы имеете в виду, говоря о неудобствах управления хостингом в ScrollViewer. В шаблоне ListBox по умолчанию используется ScrollViewer. ListView не существует в Silverlight. - person JontyMC; 14.10.2011

Установите фиксированную ширину и высоту средства просмотра прокрутки в зависимости от размера строки и столбца сетки. это помогает фиксированному размеру во время выполнения. как это

<ScrollViewer VerticalScrollBarVisibility="Auto" VerticalAlignment="Top" HorizontalScrollBarVisibility="Auto" Width="135" Height="463">
 <ListBox ItemsSource="{Binding Items}">
    <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical"></StackPanel>
      </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
      <DataTemplate>
       <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left" Orientation="Vertical">
          <RichTextBox>
             <Paragraph>
                <Run Text="{Binding}"/>
             </Paragraph>
          </RichTextBox>
       </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

I hope its helpful

person Anand Thangappan    schedule 08.10.2011
comment
Установка фиксированного размера ScrollViewer означала, что полосы прокрутки вообще не отображались. - person JontyMC; 11.10.2011
comment
Если размер списка увеличивается больше, чем высота или ширина средства просмотра прокрутки, автоматически появятся полосы прокрутки. Если вы хотите всегда использовать полосы прокрутки, включите VerticalScrollBarVisibility и HorizontalScrollBarVisibility в scrollviewer. мне дали автоматический режим - person Anand Thangappan; 12.10.2011

попробуйте установить для высоты списка значение auto и зафиксировать высоту scrollviewer. таким образом полосы прокрутки отображаются только тогда, когда высота списка больше, чем высота средства просмотра прокрутки.

Но, глядя на то, как определены объекты. В будущем у тебя будет одна большая проблема. То есть в SL4 списки занимают высоту и не возвращают ее. Поэтому, если у вас есть что-то, что расширяется внутри списка (например, элементы аккордеона) или разрешает удаление внутри списка, список будет расширен, чтобы отобразить все его элементы. Но как только элемент будет удален, он никогда не вернет высоту. В результате полоса прокрутки будет отображаться всегда, даже если внизу нечего показывать.

Это совершенно не по теме, но я чувствовал, что должен сообщить вам.

Надеюсь, я помог, если не сейчас, то на будущее.

person Nathan    schedule 12.10.2011

Наконец-то я нашел решение этой проблемы. Я удалил ScrollViewer из шаблона RichTextBox.

person JontyMC    schedule 10.11.2011

Установите MaxHeight в Listbox, это позволит программе scrollviewer отображаться только тогда, когда размеры экрана слишком малы.

person TChadwick    schedule 25.10.2012

Большое спасибо! Ты только что спас мне дни боли и страданий ... :)

Для тех (вроде меня), которым интересно, как удалить средство просмотра прокрутки из шаблона rtb: Извлеките шаблон с помощью blend. Найдите элемент scrollviewer и замените его стековой панелью (сохраните атрибут x: name).

person Aurélien Personnaz    schedule 04.04.2014