Мне нужна ваша помощь для реализации Paging
на Treeview
в WPF. Для этого я перепробовал 1 полный день и создал пример кода, но не смог добиться того, чего хочу.
Данные древовидной структуры должны быть изменены, если пользователь перемещается по элементу управления пейджингом
Логически я создал один DataPager
элемент управления и пытаюсь назначить его как Itemsource
Treeview, но не могу завершить.
Пожалуйста, предложите и помогите мне реализовать разбиение на страницы в элементе управления Treeview, так что за один раз должно отображаться только 10 записей, а когда пользователь нажимает на следующую страницу, должны отображаться еще 10 записей, начиная с 11-20
Window1.xaml
<Window x:Class="WPFTreeViewTutorial.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:WPFTreeViewTutorial"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="335" Width="441">
<Window.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Window.Resources>
<StackPanel>
<Grid>
<TreeView x:Name="trvMenu" Margin="30,50" Height="200">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Path=CurrentPage,ElementName=dataPager1}" DataType="{x:Type local:DataPager}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
<local:DataPager x:Name="dataPager1" ItemsPerPage="10"/>
</StackPanel>
Window1.xaml.cs
namespace WPFTreeViewTutorial
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
ObservableCollection<Object> People = new ObservableCollection<Object>();
for (int i = 0; i < 100; i++)
People.Add(new Person());
dataPager1.ItemsSource = People;
}
}
public class Person
{
private static int count;
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Person()
{
ID = count + 1;
Name = "Name " + count.ToString();
Age = 20 + count % 2;
count++;
}
}
}
DataPager.xaml
<UserControl x:Class="WPFTreeViewTutorial.DataPager"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Margin" Value="2"/>
</Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal">
<Button Content="<<" x:Name="FirstPage" Click="FirstPage_Click"/>
<Button Content="<" x:Name="PreviousPage" Click="PreviousPage_Click"/>
<TextBox Width="30" x:Name="page" Margin="2" BorderBrush="Black" Text="{Binding CurrentPageNumber,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"/>
<Button Content="_Go" x:Name="GoPage" Click="GoPage_Click"/>
<Button Content=">" x:Name="NextPage" Click="NextPage_Click"/>
<Button Content=">>" x:Name="LastPage" Click="LastPage_Click"/>
</StackPanel>
</UserControl>
DataPager.xaml.cs
namespace WPFTreeViewTutorial
{
/// <summary>
/// Interaction logic for DataPager.xaml
/// </summary>
public partial class DataPager : UserControl, INotifyPropertyChanged
{
public DataPager()
{
InitializeComponent();
GeneratePages();
}
private void GeneratePages()
{
if (ItemsSource != null)
{
PageCount = (int)Math.Ceiling(ItemsSource.Count / (double)ItemsPerPage);
Pages = new ObservableCollection<ObservableCollection<object>>();
for (int i = 0; i < PageCount; i++)
{
ObservableCollection<object> page = new ObservableCollection<object>();
for (int j = 0; j < ItemsPerPage; j++)
{
if (i * ItemsPerPage + j > ItemsSource.Count - 1) break;
page.Add(ItemsSource[i * ItemsPerPage + j]);
}
Pages.Add(page);
}
CurrentPage = Pages[0];
CurrentPageNumber = 1;
}
}
private int PageCount;
private int _CurrentPageNumber;
private ObservableCollection<ObservableCollection<Object>> Pages;
private ObservableCollection<Object> _ItemsSource;
private ObservableCollection<Object> _CurrentPage;
public ObservableCollection<Object> CurrentPage
{
get { return _CurrentPage; }
set
{
_CurrentPage = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("CurrentPage"));
}
}
public ObservableCollection<Object> ItemsSource
{
get { return _ItemsSource; }
set
{
_ItemsSource = value;
GeneratePages();
}
}
public int CurrentPageNumber
{
get { return _CurrentPageNumber; }
set
{
_CurrentPageNumber = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("CurrentPageNumber"));
}
}
public int ItemsPerPage
{
get { return (int)GetValue(ItemsPerPageProperty); }
set { SetValue(ItemsPerPageProperty, value); }
}
public static readonly DependencyProperty ItemsPerPageProperty =
DependencyProperty.Register("ItemsPerPage", typeof(int), typeof(DataPager), new UIPropertyMetadata(10));
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private void FirstPage_Click(object sender, RoutedEventArgs e)
{
if (Pages != null)
{
CurrentPage = Pages[0];
CurrentPageNumber = 1;
}
}
private void PreviousPage_Click(object sender, RoutedEventArgs e)
{
if (Pages != null)
{
CurrentPageNumber = (CurrentPageNumber - 1) < 1 ? 1 : CurrentPageNumber - 1;
CurrentPage = Pages[CurrentPageNumber - 1];
}
}
private void NextPage_Click(object sender, RoutedEventArgs e)
{
if (Pages != null)
{
CurrentPageNumber = (CurrentPageNumber + 1) > PageCount ? PageCount : CurrentPageNumber + 1;
CurrentPage = Pages[CurrentPageNumber - 1];
}
}
private void LastPage_Click(object sender, RoutedEventArgs e)
{
if (Pages != null)
{
CurrentPage = Pages[PageCount - 1];
CurrentPageNumber = PageCount;
}
}
private void GoPage_Click(object sender, RoutedEventArgs e)
{
if (Pages != null)
{
CurrentPage = Pages[CurrentPageNumber - 1];
}
}
}
}