刚做完一个使用了wpf技术的项目,总结一下项目中使用到的一些以前没用过的技术

DataGrid 过滤

nuget库 DataGridExtensions 提供了自定义扩展DataGrid列过滤的方法

根据例子中的MultipleChoiceFilter 可以自定义任意过滤。

我的日期过滤控件:

 // xaml: 
 <Control x:Class= "readLog.Views.Filters.DateFilter" 
          x:Name= "Control" 
              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:readLog.Views.Filters" 
              xmlns:dgx= "urn:tom-englert.de/DataGridExtensions" 
              xmlns:sys= "clr-namespace:System;assembly=mscorlib" 
              mc:Ignorable= "d" 
              d:DesignHeight= "30"  d:DesignWidth= "30" 
          >
 
     <Control.Resources>
 
         <ObjectDataProvider x:Key= "dateTypeEnum"  MethodName= "GetValues" 
                             ObjectType= "{x:Type sys:Enum}" >
 
             <ObjectDataProvider.MethodParameters>
 
                 <x:Type TypeName= "local:DateFilterType" ></x:Type>
 
             </ObjectDataProvider.MethodParameters>
 
         </ObjectDataProvider>
 
     </Control.Resources>
 
     <Control.Template>
 
         <ControlTemplate>
 
             <Grid>
 
                 <ToggleButton x:Name= "ToggleButton" >
 
                     <StackPanel Orientation= "Horizontal" >
 
                         <TextBlock x:Name= "IsFilterActiveMarker"  Text= "."  Margin= "0,0,-4,0"  Foreground= "{Binding ElementName=FilterSymbol, Path=Foreground}"  FontWeight= "Bold"  />
 
                         <Control x:Name= "FilterSymbol"  Style= "{DynamicResource {x:Static dgx:DataGridFilter.IconStyleKey}}"  />
 
                     </StackPanel>
 
                 </ToggleButton>
 
                 <Popup 
 
                     DataContext= "{Binding ElementName=Control}" 
                        x:Name= "Popup"  IsOpen= "{Binding Path=IsChecked, ElementName=ToggleButton, Mode=TwoWay}" 
                        AllowsTransparency= "True"  StaysOpen= "False" >
 
                     <StackPanel>
 
                         <ComboBox x:Name= "typeBox" 
                                   ItemsSource= "{Binding Source={StaticResource dateTypeEnum}}" 
                                   SelectedItem= "{Binding Path=FilterType}" />
 
 
 
                         <DatePicker x:Name= "begTm" 
                                     Visibility= "{Binding Path=BeginTimeVisible}" 
                                     SelectedDate= "{Binding Path=BeginTime}" 
                                     />
 
                         <DatePicker x:Name= "endTm" 
                                     Visibility= "{Binding Path=EndTimeVisible}" 
                                     SelectedDate= "{Binding Path=EndTime}" 
                         />
 
 
 
                     </StackPanel>
 
                 </Popup>
 
             </Grid>
 
         </ControlTemplate>
 
     </Control.Template>
 
 </Control>
 
 

 // 交互 
 /// <summary> 
 ///  DateFilter.xaml 的交互逻辑 
 /// </summary> 
 public partial class DateFilter  :  Control 
     {
 
 public DateFilter ( ) 
 {
 
             InitializeComponent();
 
         }
 
 
 
 # region  dependency property 
 
 
 public static readonly  DependencyProperty FilterTypeProperty = DependencyProperty.Register(
 
 "FilterType" ,  typeof (DateFilterType),  typeof (DateFilter), 
 
 new  FrameworkPropertyMetadata( default (DateFilterType), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (s, e) => ((DateFilter)s).FilterTypeChange()));
 
 
 
 
 
 private void FilterTypeChange ( ) 
 {
 
 // 可见性 
 switch  (FilterType)
 
             {
 
 case  DateFilterType.All:
 
 case  DateFilterType.ThisYear:
 
 case  DateFilterType.ThisMonth:
 
 case  DateFilterType.PreYear:
 
 case  DateFilterType.PreMonth:
 
                     BeginTimeVisible = Visibility.Collapsed;
 
                     EndTimeVisible = Visibility.Collapsed;
 
 break ;
 
 case  DateFilterType.Earlier:
 
                     BeginTimeVisible = Visibility.Collapsed;
 
                     EndTimeVisible = Visibility.Visible;
 
 break ;
 
 case  DateFilterType.Later:
 
                     BeginTimeVisible = Visibility.Visible;
 
                     EndTimeVisible = Visibility.Collapsed;
 
 break ;
 
 case  DateFilterType.Between:
 
                     BeginTimeVisible = Visibility.Visible;
 
                     EndTimeVisible = Visibility.Visible;
 
 break ;
 
 default :
 
 throw new  ArgumentOutOfRangeException();
 
             }
 
 
 
             RangeChanged();
 
         }
 
 
 
 private void RangeChanged ( ) 
 {
 
             Filter =  new  ContentFilter(FilterType, BeginTime, EndTime);
 
         }
 
 
 
 
 
 public  DateFilterType FilterType
 
         {
 
 get  => (DateFilterType) GetValue(FilterTypeProperty);
 
 set  => SetValue(FilterTypeProperty,  value );
 
         }
 
 
 
 public static readonly  DependencyProperty FilterProperty = DependencyProperty.Register(
 
 "Filter" ,  typeof (ContentFilter),  typeof (DateFilter), 
 
 new  FrameworkPropertyMetadata( default (ContentFilter), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (s, e) => ((DateFilter)s).FilterChanged()));
 
 
 
 public  ContentFilter Filter
 
         {
 
 get  => (ContentFilter) GetValue(FilterProperty);
 
 set  => SetValue(FilterProperty,  value );
 
         }
 
 
 
 private void FilterChanged ( ) 
 {
 
 var  filter = Filter  as  ContentFilter;
 
 if  ( null  == filter)
 
             {
 
 return ;
 
             }
 
 
 
             FilterType = filter.FilterType;
 
             BeginTime = filter.BeginTime;
 
             EndTime = filter.EndTime;
 
         }
 
 
 
 public static readonly  DependencyProperty BeginTimeProperty = DependencyProperty.Register(
 
 "BeginTime" ,  typeof (DateTime),  typeof (DateFilter),
 
 new  FrameworkPropertyMetadata(DateTime.Today, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,(s, e) => ((DateFilter)s).RangeChanged()));
 
 
 
 public  DateTime BeginTime
 
         {
 
 get  => (DateTime) GetValue(BeginTimeProperty);
 
 set  => SetValue(BeginTimeProperty,  value );
 
         }
 
 
 
 public static readonly  DependencyProperty EndTimeProperty = DependencyProperty.Register(
 
 "EndTime" ,  typeof (DateTime),  typeof (DateFilter),
 
 new  FrameworkPropertyMetadata(DateTime.Today, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,(s, e) => ((DateFilter)s).RangeChanged()));
 
 
 
 public  DateTime EndTime
 
         {
 
 get  => (DateTime) GetValue(EndTimeProperty);
 
 set  => SetValue(EndTimeProperty,  value );
 
         }
 
 
 
 public static readonly  DependencyProperty PropertyTypeProperty = DependencyProperty.Register(
 
 "BeginTimeVisible" ,  typeof (Visibility),  typeof (DateFilter),
 
 new  FrameworkPropertyMetadata(Visibility.Collapsed, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (s, e) => ((DateFilter)s).RangeChanged()));
 
 
 
 public  Visibility BeginTimeVisible
 
         {
 
 get  => (Visibility) GetValue(PropertyTypeProperty);
 
 set  => SetValue(PropertyTypeProperty,  value );
 
         }
 
 
 
 public static readonly  DependencyProperty EndTimeVisibleProperty = DependencyProperty.Register(
 
 "EndTimeVisible" ,  typeof (Visibility),  typeof (DateFilter), 
 
 new  FrameworkPropertyMetadata(Visibility.Collapsed, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (s, e) => ((DateFilter)s).RangeChanged()));
 
 
 
 public  Visibility EndTimeVisible
 
         {
 
 get  => (Visibility) GetValue(EndTimeVisibleProperty);
 
 set  => SetValue(EndTimeVisibleProperty,  value );
 
         }
 
 
 
 
 
 
 
 # endregion 
 
 
 public class ContentFilter  :  IContentFilter 
         {
 
 public ContentFilter ( DateFilterType type, DateTime beg, DateTime end ) 
 {
 
                 FilterType = type;
 
                 BeginTime = beg;
 
                 EndTime = end;
 
             }
 
 
 
 public bool IsMatch ( object value ) 
 {
 
 if  ( null  ==  value )
 
                 {
 
 return false ;
 
                 }
 
 
 
 try 
                 {
 
 var  tm = (DateTime)  value ;
 
 
 
 switch  (FilterType)
 
                     {
 
 case  DateFilterType.All:
 
 return true ;
 
 case  DateFilterType.ThisYear:
 
 return  IsMatchYear(tm, DateTime.Today);
 
 case  DateFilterType.ThisMonth:
 
 return  IsMatchMonth(tm, DateTime.Today);
 
 case  DateFilterType.PreYear:
 
 return  IsMatchYear(tm, DateTime.Today.AddYears( -1 ));
 
 case  DateFilterType.PreMonth:
 
 return  IsMatchMonth(tm, DateTime.Today.AddMonths( -1 ));
 
 case  DateFilterType.Earlier:
 
 return  tm.Date <= EndTime.Date;
 
 case  DateFilterType.Later:
 
 return  tm.Date >= BeginTime.Date;
 
 case  DateFilterType.Between:
 
 return  IsMatchDate(tm, BeginTime, EndTime);
 
 default :
 
 throw new  ArgumentOutOfRangeException();
 
                     }
 
                 }
 
 catch  (Exception e)
 
                 {
 
 return false ;
 
                 }
 
 
 
             }
 
 
 
 
 
 public  DateFilterType FilterType {  get ; }
 
 
 
 public  DateTime BeginTime {  get ; }
 
 
 
 public  DateTime EndTime {  get ; }
 
 
 
 # region  Datetime 
 private bool IsMatchMonth ( DateTime tm, DateTime toMatch ) 
 {
 
 return  IsMatchDate(tm, GetFirstDayOfMonth(toMatch), GetLastDayOfMonth(toMatch));
 
             }
 
 
 
 private bool IsMatchDate ( DateTime tm, DateTime beg, DateTime end ) 
 {
 
                 tm = tm.Date;
 
 return  tm <= beg && tm >= end;
 
             }
 
 
 
 private bool IsMatchYear ( DateTime tm, DateTime toMatch ) 
 {
 
 return  IsMatchDate(tm, GetLastDayOfYear(toMatch), GetFirstDayOfYear(toMatch));
 
             }
 
 
 
 private  DateTime  GetFirstDayOfMonth ( DateTime dt ) 
 {
 
 var  dtFrom = dt;
 
                 dtFrom = dtFrom.AddDays(-(dtFrom.Day -  1 ));
 
 
 
 return  dtFrom;
 
             }
 
 
 
 private  DateTime  GetLastDayOfMonth ( DateTime dt ) 
 {
 
 var  dtTo = dt;
 
                 dtTo = dtTo.AddMonths( 1 );
 
                 dtTo = dtTo.AddDays(-(dtTo.Day));
 
 return  dtTo;
 
             }
 
 
 
 private  DateTime  GetFirstDayOfYear ( DateTime dt ) 
 {
 
 var  dtFrom = dt;
 
                 dtFrom = dtFrom.AddMonths(-(dtFrom.Month -  1 ));
 
 return  GetFirstDayOfMonth(dtFrom);
 
             }
 
 
 
 private  DateTime  GetLastDayOfYear ( DateTime dt ) 
 {
 
 var  dtTo = dt;
 
                 dtTo = dtTo.AddYears( 1 );
 
                 dtTo = dtTo.AddMonths(-dt.Month);
 
 
 
 return  GetLastDayOfMonth(dtTo);
 
             }
 
 
 
 
 
 # endregion 
         }
 
     }
 
 
 
     [TypeConverter( typeof (EnumDescriptionTypeConverter))]
 
 public enum  DateFilterType
 
     {
 
         [Description( "所有" )]
 
         All,  // 全部 
         [Description( "今年" )]
 
         ThisYear,
 
         [Description( "本月" )]
 
         ThisMonth,
 
         [Description( "去年" )]
 
         PreYear,
 
         [Description( "上个月" )]
 
         PreMonth,
 
         [Description( "指定日期以前" )]
 
         Earlier,
 
         [Description( "指定日期以后" )]
 
         Later,
 
         [Description( "之间" )]
 
         Between,
 
 
 
 
 
     }
 
 

枚举显示

枚举显示有两个方案,

  1. 转换器, 在xaml中定义一个转换器资源
  2. 定义一个用来显示的字符串属性,界面绑定这个字符串属性。

读取DataGrid某一行某一列的值

从控件 DataGridExtensions 中学习到的。拿到的是真实的绑定对象,而不是显示的字符串。一开始用 GetCelllContent(),但对未显示的行无法取到。

 class GetCellValueClass  :  DependencyObject 
         {
 
 /// <summary> 
 ///  Identifies the CellValue dependency property, a private helper property used to evaluate the property path for the list items. 
 /// </summary> 
 private static readonly  DependencyProperty _cellValueProperty =
 
                 DependencyProperty.Register( "_cellValue" ,  typeof ( object ),  typeof (GetCellValueClass));
 
 
 
 public object GetCellValue ( DataGridColumn col,  object  item ) 
 {
 
 var  propertyPath = col.SortMemberPath;
 
 if  ( string .IsNullOrEmpty(propertyPath))
 
 return null ;
 
 
 
                 BindingOperations.SetBinding( this , _cellValueProperty,  new  Binding(propertyPath) { Source = item });
 
 var  propertyValue = GetValue(_cellValueProperty);
 
                 BindingOperations.ClearBinding( this , _cellValueProperty);
 
 
 
 return  propertyValue;
 
             }
 
 
 
 
 
         }
 
 

使用方法:

 new  GetCellValueClass().GetCellValue(col, item);

  • 打赏
  • 分享
分享到...
请选择打赏方式
  • 微信
  • 支付宝

By yhl

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注