Ниже кода реализуются 1 и 2. Элемент в середине горизонтального списка всегда выбран. Для того чтобы внешний вид списка выглядел хорошо, нужно, чтобы стиль отображался как, например, использование непрозрачности, чтобы показать, какие элементы отображаются, а какие нет.
XAML:
<Window x:Class="FlowListTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<ListBox
ItemsSource="{Binding Path=Items}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.ScrollChanged="OnScrollChanged"
SelectionChanged="OnSelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border CornerRadius="10" BorderBrush="Red" BorderThickness="2">
<TextBlock Text="{Binding}" Margin="5" Width="20" Height="100"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
Код:
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace FlowListTest
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = this;
}
public IEnumerable<string> Items
{
get
{
for (int i = 0; i < 100; i++)
{
yield return i.ToString();
}
}
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
(sender as ListBox).SelectedIndex = _selectedIndex;
}
private void OnScrollChanged(object sender, ScrollChangedEventArgs e)
{
_selectedIndex = (int)(e.HorizontalOffset + Math.Truncate(e.ViewportWidth / 2));
(sender as ListBox).SelectedIndex = _selectedIndex;
}
private int _selectedIndex;
}
}