1. 程式人生 > >WPF 迴圈顯示列表

WPF 迴圈顯示列表

專案需要類似手機上設定時間的控制元件,可以一直滾動顯示的內容連續的。在WPF中找到的列表控制元件只能滾到最後再反向滾動。

基於ScrollViewer和StackPanel來改造,Xaml如下:

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="{Binding RelativeSource={RelativeSource AncestorType=local:ScrollList},Path=ItemHeight}"
/>
<RowDefinition/> </Grid.RowDefinitions> <ScrollViewer x:Name="tt" Grid.RowSpan="3" PreviewMouseWheel="tt_PreviewMouseWheel" ScrollViewer.VerticalScrollBarVisibility="Hidden" > <StackPanel x:Name="stacktt" Background="Gray"> </StackPanel
>
</ScrollViewer> <Rectangle Height="1" Fill="Red" Grid.Row="1" VerticalAlignment="Top"/> <Rectangle Height="1" Fill="Red" Grid.Row="1" VerticalAlignment="Bottom"/> </Grid>

cs程式碼如下:

    public partial class ScrollList : UserControl
    {
        public
ScrollList() { InitializeComponent(); this.Loaded += ScrollList_Loaded; } private void ScrollList_Loaded(object sender, RoutedEventArgs e) { stacktt.Children.Clear(); for (int index = 0; index < ShowItemCount; index++) { TextBlock text = new TextBlock() { Height=ItemHeight}; stacktt.Children.Add(text); } RefreshData(); } public List<int> DataSource { get { return (List<int>)GetValue(DataSourceProperty); } set { SetValue(DataSourceProperty, value); } } // Using a DependencyProperty as the backing store for DataSource. This enables animation, styling, binding, etc... public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", typeof(List<int>), typeof(ScrollList), new PropertyMetadata(new List<int>())); public int SelectData { get { return (int)GetValue(SelectDataProperty); } set { SetValue(SelectDataProperty, value); } } // Using a DependencyProperty as the backing store for SelectData. This enables animation, styling, binding, etc... public static readonly DependencyProperty SelectDataProperty = DependencyProperty.Register("SelectData", typeof(int), typeof(ScrollList), new PropertyMetadata(0)); public int ItemHeight { get { return (int)GetValue(ItemHeightProperty); } set { SetValue(ItemHeightProperty, value); } } // Using a DependencyProperty as the backing store for ItemHeight. This enables animation, styling, binding, etc... public static readonly DependencyProperty ItemHeightProperty = DependencyProperty.Register("ItemHeight", typeof(int), typeof(ScrollList), new PropertyMetadata(20)); int ShowItemCount { get { return (int)ActualHeight / ItemHeight; } } int startIndex = 0; private void tt_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { Console.WriteLine("TimeStap={0} Delta={1}", e.Timestamp, e.Delta); if (DataSource.Count == 0) return; if (e.Delta > 0) { if ((startIndex + ShowItemCount) < DataSource.Count) { startIndex += 1; } else { startIndex = 0; } } else { if ((startIndex - ShowItemCount) < 0) { startIndex = DataSource.Count - 1; } else { startIndex -= 1; } } RefreshData(); } private void RefreshData() { if (DataSource.Count > 0) { int count = 0; foreach (var item in stacktt.Children) { if ((startIndex + count) > (DataSource.Count - 1)) { (item as TextBlock).Text = DataSource[startIndex + count - DataSource.Count].ToString(); } else { (item as TextBlock).Text = DataSource[startIndex + count].ToString(); } count += 1; } TextBlock selectText = (TextBlock)VisualTreeHelper.GetChild(stacktt, ShowItemCount / 2); if (ShowItemCount%2 != 0) { selectText = (TextBlock)VisualTreeHelper.GetChild(stacktt, ShowItemCount / 2+1); } SelectData = Convert.ToInt32(selectText.Text); } } }

測試介面

程式碼連結地址