zoukankan      html  css  js  c++  java
  • wpf 自定义控件(包含依赖属性以及事件)

    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

  • 相关阅读:
    mybatis模糊查询语句
    Java中解压文件名有中文的rar包出现乱码问题的解决
    tomcat服务器开启gzip功能的方法
    asp.net 操作word
    asp.net webservice 返回json数据乱码解决方法
    阿里云服务器mysql修改编码问题
    阿里云服务器问题:访问
    EasyUI 在aspx页面显示高度不正常解决办法
    C# 或 JQuery导出Excel
    如何分离数据库 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/anjingdian/p/15499336.html
Copyright © 2011-2022 走看看