wpf 事件https://blog.csdn.net/weixin_44240082/article/details/99062899
創建了這個依賴屬性,就可以直接在對應的控件中使用了,就像是button中一開始就內置的width等屬性一樣,這個在設計自定義控件的時候用的尤其多
https://www.cnblogs.com/yang-fei/p/4724899.html 分頁
下面講的是自定義分頁控件代碼:
<UserControl x:Class="WPFDataGridPaging.Pager" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPFDataGridPaging" mc:Ignorable="d" d:DesignHeight="30" d:DesignWidth="220"> <UserControl.Resources> <Style TargetType="{x:Type Button}"> <Setter Property="Width" Value="22"/> <Setter Property="Height" Value="22"/> </Style> </UserControl.Resources> <Grid> <StackPanel Orientation="Horizontal"> <Button x:Name="FirstPageButton" Margin="5,0" Click="FirstPageButton_Click"> <Path Width="7" Height="10" Data="M0,0L0,10 M0,5L6,2 6,8 0,5" Stroke="Black" StrokeThickness="1"
Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center" /> </Button> <Button x:Name="PreviousPageButton" Margin="0,0,5,0" Click="PreviousPageButton_Click"> <Path Width="8" Height="8" Data="M0,4L8,0 8,8z" Stroke="Black" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center" /> </Button> <TextBlock VerticalAlignment="Center"> <Run Text="第"/> <Run x:Name="rCurrent" Text="0"/> <Run Text="頁"/> </TextBlock> <Button Margin="5,0" x:Name="NextPageButton" Click="NextPageButton_Click"> <Path Width="8" Height="8" Data="M0,4L8,0 8,8z" Stroke="Black" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center"> <Path.RenderTransform> <RotateTransform Angle="180" CenterX="4" CenterY="4" /> </Path.RenderTransform> </Path> </Button> <Button Margin="0,0,5,0" x:Name="LastPageButton" Click="LastPageButton_Click"> <Path x:Name="MainPath" Width="7" Height="10" Data="M0,0L0,10 M0,5 L6,2 6,8 0,5"
Stroke="Black" StrokeThickness="1" Fill="Black" VerticalAlignment="Center" HorizontalAlignment="Center"> <Path.RenderTransform> <RotateTransform Angle="180" CenterX="3" CenterY="5" /> </Path.RenderTransform> </Path> </Button> <TextBlock VerticalAlignment="Center"> <Run Text="共"/> <Run x:Name="rTotal" Text="0"/> <Run Text="頁"/> </TextBlock> </StackPanel> </Grid> </UserControl>
界面:
![]()
后台代碼:
public partial class Pager : UserControl { #region 聲明事件和依賴屬性 public static RoutedEvent FirstPageEvent; public static RoutedEvent PreviousPageEvent; public static RoutedEvent NextPageEvent; public static RoutedEvent LastPageEvent; public static readonly DependencyProperty CurrentPageProperty; public static readonly DependencyProperty TotalPageProperty; #endregion public string CurrentPage { get { return (string)GetValue(CurrentPageProperty); } set { SetValue(CurrentPageProperty, value); } } public string TotalPage { get { return (string)GetValue(TotalPageProperty); } set { SetValue(TotalPageProperty, value); } } public Pager() { InitializeComponent(); } static Pager() { #region 注冊事件以及依賴屬性 //注冊FirstPageEvent事件,事件的擁有者是Pager,路由事件的名稱是FirstPage,這是唯一的 FirstPageEvent = EventManager.RegisterRoutedEvent("FirstPage", RoutingStrategy.Direct,
typeof(RoutedEventHandler), typeof(Pager)); PreviousPageEvent = EventManager.RegisterRoutedEvent("PreviousPage", RoutingStrategy.Direct,
typeof(RoutedEventHandler), typeof(Pager)); NextPageEvent = EventManager.RegisterRoutedEvent("NextPage", RoutingStrategy.Direct,
typeof(RoutedEventHandler), typeof(Pager)); LastPageEvent = EventManager.RegisterRoutedEvent("LastPage", RoutingStrategy.Direct,
typeof(RoutedEventHandler), typeof(Pager)); //注冊自定義的依賴屬性 CurrentPageProperty = DependencyProperty.Register("CurrentPage",
typeof(string), typeof(Pager), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnCurrentPageChanged))); TotalPageProperty = DependencyProperty.Register("TotalPage",
typeof(string), typeof(Pager), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnTotalPageChanged))); #endregion } public event RoutedEventHandler FirstPage { add { AddHandler(FirstPageEvent, value); } remove { RemoveHandler(FirstPageEvent, value); } } public event RoutedEventHandler PreviousPage { add { AddHandler(PreviousPageEvent, value); } remove { RemoveHandler(PreviousPageEvent, value); } } public event RoutedEventHandler NextPage { add { AddHandler(NextPageEvent, value); } remove { RemoveHandler(NextPageEvent, value); } } public event RoutedEventHandler LastPage { add { AddHandler(LastPageEvent, value); } remove { RemoveHandler(LastPageEvent, value); } } /// <summary> /// 依賴屬性回調方法 /// </summary> /// <param name="d"></param> /// <param name="e"></param> public static void OnTotalPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Pager p = d as Pager; if (p != null) { Run rTotal = (Run)p.FindName("rTotal"); rTotal.Text = (string)e.NewValue; } } private static void OnCurrentPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Pager p = d as Pager; if (p != null) { Run rCurrrent = (Run)p.FindName("rCurrent"); rCurrrent.Text = (string)e.NewValue; } } private void FirstPageButton_Click(object sender, RoutedEventArgs e) { RaiseEvent(new RoutedEventArgs(FirstPageEvent, this)); } private void PreviousPageButton_Click(object sender, RoutedEventArgs e) { RaiseEvent(new RoutedEventArgs(PreviousPageEvent, this)); } private void NextPageButton_Click(object sender, RoutedEventArgs e) { RaiseEvent(new RoutedEventArgs(NextPageEvent, this)); } private void LastPageButton_Click(object sender, RoutedEventArgs e) { RaiseEvent(new RoutedEventArgs(LastPageEvent, this)); } }
上面就是自定義的一個分頁控件,如果我們想要使用這個控件,如下:
<Window x:Class="WPFDataGridPaging.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:local="clr-namespace:WPFDataGridPaging" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <DataGrid Grid.Row="0" ItemsSource="{Binding FakeSource}" AutoGenerateColumns="False" CanUserAddRows="False"> <DataGrid.Columns> <DataGridTextColumn Header="Item Id" Binding="{Binding Id}" Width="80"/> <DataGridTextColumn Header="Item Name" Binding="{Binding ItemName}" Width="180"/> </DataGrid.Columns> </DataGrid> <!-- TotalPage 和CurrentPage就是在Pager中自定義的依賴屬性,可以在這里直接來用--> <local:Pager TotalPage="{Binding TotalPage}" CurrentPage="{Binding CurrentPage, Mode=TwoWay}" HorizontalAlignment="Center" Grid.Row="1"> <i:Interaction.Triggers> <!--EventName="FirstPage" 這里FirstPage就是前面注冊事件的時候默認的事件名稱,必須要唯一 --> <i:EventTrigger EventName="FirstPage"> <i:InvokeCommandAction Command="{Binding FirstPageCommand}" /> </i:EventTrigger> <i:EventTrigger EventName="PreviousPage"> <i:InvokeCommandAction Command="{Binding PreviousPageCommand}"/> </i:EventTrigger> <i:EventTrigger EventName="NextPage"> <i:InvokeCommandAction Command="{Binding NextPageCommand}" /> </i:EventTrigger> <i:EventTrigger EventName="LastPage"> <i:InvokeCommandAction Command="{Binding LastPageCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </local:Pager> </Grid> </Window>
界面:

后台代碼:
/// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); //這里一定要注意,一定要將模型加到上下文中,要不然依賴屬性和事件都不會觸發,在實際開發中是不可能一打開 //界面就開始加載出來數據的,所以可以通過ObservableCollection形式綁定表格數據, //而需要綁定事件和依賴屬性的需要將其綁定到上下文中 DataContext = new MainViewModel(); } }
MainViewModel:
public class MainViewModel : ViewModel { private ICommand _firstPageCommand; public ICommand FirstPageCommand { get { return _firstPageCommand; } set { _firstPageCommand = value; } } private ICommand _previousPageCommand; public ICommand PreviousPageCommand { get { return _previousPageCommand; } set { _previousPageCommand = value; } } private ICommand _nextPageCommand; public ICommand NextPageCommand { get { return _nextPageCommand; } set { _nextPageCommand = value; } } private ICommand _lastPageCommand; public ICommand LastPageCommand { get { return _lastPageCommand; } set { _lastPageCommand = value; } } private int _pageSize; public int PageSize { get { return _pageSize; } set { if(_pageSize != value) { _pageSize = value; OnPropertyChanged("PageSize"); } } } private int _currentPage; public int CurrentPage { get { return _currentPage; } set { if(_currentPage != value) { _currentPage = value; OnPropertyChanged("CurrentPage"); } } } private int _totalPage; public int TotalPage { get { return _totalPage; } set { if(_totalPage != value) { _totalPage = value; OnPropertyChanged("TotalPage"); } } } /// <summary> /// ObservableCollection表示一個動態數據集合,它可在添加、刪除項目或刷新整個列表時提供通知。 /// 在xaml中綁定FakeSource之后,運行中FakeSource這里的數據改變的話 /// </summary> private ObservableCollection<FakeDatabase> _fakeSoruce; public ObservableCollection<FakeDatabase> FakeSource { get { return _fakeSoruce; } set { if(_fakeSoruce != value) { _fakeSoruce = value; OnPropertyChanged("FakeSource"); } } } private List<FakeDatabase> _source; public MainViewModel() { _currentPage = 1; _pageSize = 20; FakeDatabase fake = new FakeDatabase(); _source = fake.GenerateFakeSource(); _totalPage = _source.Count / _pageSize; _fakeSoruce = new ObservableCollection<FakeDatabase>(); List<FakeDatabase> result = _source.Take(20).ToList(); _fakeSoruce.Clear(); _fakeSoruce.AddRange(result); _firstPageCommand = new DelegateCommand(FirstPageAction); _previousPageCommand = new DelegateCommand(PreviousPageAction); _nextPageCommand = new DelegateCommand(NextPageAction); _lastPageCommand = new DelegateCommand(LastPageAction); } private void FirstPageAction() { CurrentPage = 1; var result = _source.Take(_pageSize).ToList(); _fakeSoruce.Clear(); _fakeSoruce.AddRange(result); } private void PreviousPageAction() { if(CurrentPage == 1) { return; } List<FakeDatabase> result = new List<FakeDatabase>(); if(CurrentPage == 2) { result = _source.Take(_pageSize).ToList(); } else { result = _source.Skip((CurrentPage - 2) * _pageSize).Take(_pageSize).ToList(); } _fakeSoruce.Clear(); _fakeSoruce.AddRange(result); CurrentPage--; } private void NextPageAction() { if(CurrentPage == _totalPage) { return; } List<FakeDatabase> result = new List<FakeDatabase>(); result = _source.Skip(CurrentPage * _pageSize).Take(_pageSize).ToList(); _fakeSoruce.Clear(); _fakeSoruce.AddRange(result); CurrentPage++; } private void LastPageAction() { CurrentPage = TotalPage; int skipCount = (_totalPage - 1) * _pageSize; int takeCount = _source.Count - skipCount; var result = _source.Skip(skipCount).Take(takeCount).ToList(); _fakeSoruce.Clear(); _fakeSoruce.AddRange(result); } }
其它補充代碼:
DelegateCommand
public class DelegateCommand<T> : ICommand { private static bool CanExecute(T parameter) { return true; } private readonly Action<T> _execute; private Func<T, bool> _canExecute; public DelegateCommand(Action<T> execute, Func<T, bool> canExecute = null) { if (execute == null) { throw new ArgumentNullException("execute is null."); } _execute = execute; _canExecute = canExecute ?? CanExecute; } public bool CanExecute(object parameter) { return _canExecute(TranslateParameter(parameter)); } public event EventHandler CanExecuteChanged { add { if (_canExecute != null) { CommandManager.RequerySuggested += value; } } remove { if (_canExecute != null) { CommandManager.RequerySuggested -= value; } } } public void Execute(object parameter) { _execute(TranslateParameter(parameter)); } private T TranslateParameter(object parameter) { T value = default(T); if (parameter != null && typeof(T).IsEnum) value = (T)Enum.Parse(typeof(T), (string)parameter); else value = (T)parameter; return value; } } public class DelegateCommand : DelegateCommand<object> { public DelegateCommand(Action execute,Func<bool> canExecute = null) : base(obj => execute(), (canExecute == null ? null : new Func<object, bool>(obj => canExecute()))) { } }
FakeDatabase
public class FakeDatabase { public int Id { get; set; } public string ItemName { get; set; } public List<FakeDatabase> GenerateFakeSource() { List<FakeDatabase> source = new List<FakeDatabase>(); for (int i = 0; i < 1000; i++) { FakeDatabase item = new FakeDatabase() { Id = i, ItemName = "Item" + i.ToString() }; source.Add(item); } return source; } public FakeDatabase() { } }
Extension
public static class Extension { public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items) { items.ToList().ForEach(collection.Add); } }
ViewModel
public class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
本文中的代碼轉自於博客:https://www.cnblogs.com/yang-fei/p/4724899.html
ViewModel
