#wpf #datagrid #listbox #scroll
#wpf #datagrid #listbox #прокрутка
Вопрос:
Я пытаюсь создать макет, который использует ListBox
и мой пользовательский заголовок, который выглядит как линейка, но для дат (с явными начальными и конечными датами). Цель состоит в том, чтобы иметь внешний вид и чувствовать себя похожим на a DataGrid
, за исключением того, что строка заголовка столбца будет заменена моим DateTape
объектом. Когда пользователь прокручивает по горизонтали, DateTape
ListBox
прокручиваются и оба, но когда пользователь прокручивает по вертикали, только ListBox
прокручиваются и DateTape
остаются вверху (например, строка заголовка столбца в DataGrid
).
Пока лучшее, что я смог сделать, это следующее:
<Window x:Class="ProjectNS.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:ProjectNS"
Title="MainWindow" Height="350" Width="600">
<Window.Resources>
<DataTemplate x:Key="itemTemplate">
<my:CustomRectangle HorizontalAlignment="Left" VerticalAlignment="Top" />
</DataTemplate>
</Window.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="File" />
</Menu>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<DockPanel>
<my:DateTape DockPanel.Dock="Top" VerticalAlignment="Top">
<my:DateTape.Dates>
<CalendarDateRange Start="10/4/2011" End="11/4/2011" />
</my:DateTape.Dates>
</my:DateTape>
<ListBox ItemTemplate="{StaticResource itemTemplate}" />
</DockPanel>
</ScrollViewer>
</DockPanel>
</Window>
Единственная проблема, с которой я сталкиваюсь с этим решением, заключается в том, что вертикальная полоса прокрутки для ListBox
элемента управления находится в крайнем правом углу, что означает, что пользователь должен прокручивать горизонтально, чтобы появилась полоса прокрутки. Мне нужна полоса прокрутки, видимая всегда.
Я попытался поместить DateTape
и ListBox
в a ScrollViewer
, но затем DateTape
прокручивается вне поля зрения при прокрутке по вертикали.
К вашему СВЕДЕНИЮ — мой CustomRectangle
объект UserControl
— это объект, который позволяет пользователю регулировать горизонтальное положение и ширину в режиме реального времени, чтобы расположить его по желанию в соответствии с DateTape
.
Ответ №1:
В итоге мне пришлось немного реструктурировать. Теперь ListBox
ItemsControl
он вложен в a ScrollViewer
со скрытой вертикальной полосой прокрутки (не отключен). У меня также есть независимая ScrollBar
привязка к правой стороне, которая привязана к вертикальной полосе прокрутки ScrollViewer
в коде. Это обрабатывает вертикальную прокрутку. Наконец, вторичный ScrollViewer
файл содержит DateTape
и ItemsControl
набор для обработки горизонтальной прокрутки.
XAML
<DockPanel x:Name="dockPanel">
<Menu DockPanel.Dock="Top">
<MenuItem Header="File" />
</Menu>
<ScrollBar x:Name="verticalScrollBar"
DockPanel.Dock="Right"
SmallChange="1"
LargeChange="3"
Scroll="verticalScrollBar_Scroll"
SizeChanged="verticalScrollBar_SizeChanged"
Style="{StaticResource scrollBarHiderStyle}"
Maximum="{Binding ElementName=listScroller, Path=ScrollableHeight}" />
<ScrollViewer x:Name="dateScroller"
VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="Auto"
DockPanel.Dock="Top">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<my:DateTape x:Name="dateTape"
DockPanel.Dock="Top"
VerticalAlignment="Top"
Dates="{Binding Source={StaticResource dateRange}}" />
<ScrollViewer x:Name="listScroller" VerticalScrollBarVisibility="Hidden" Grid.Row="1" Foreground="{x:Null}" Panel.ZIndex="1">
<ItemsControl x:Name="itemsList"
ItemTemplate="{StaticResource itemTemplate}"/>
</ScrollViewer>
</Grid>
</ScrollViewer>
</DockPanel>
C#
// this function merely sets the scroll bar thumb size
private void verticalScrollBar_SizeChanged(object sender, SizeChangedEventArgs e)
{
verticalScrollBar.Track.ViewportSize = itemsList.ActualHeight / 2;
}
// this function links the scroll bar to the scrollviewer
private void verticalScrollBar_Scroll(object sender, System.Windows.Controls.Primitives.ScrollEventArgs e)
{
listScroller.ScrollToVerticalOffset(e.NewValue);
}
Я попытался привязать независимый ScrollBar
к полосе прокрутки при ItemsControl
использовании a ItemsPanelTemplate
, но я не смог заставить это работать.