仅在日期过滤Telerik MVC网格(忽略时间值)

仅在日期过滤Telerik MVC网格(忽略时间值),telerik,telerik-grid,telerik-mvc,Telerik,Telerik Grid,Telerik Mvc,我在Telerik MVC网格中有一列是DateTime类型的。我只想将它的日期部分用于显示和过滤。因此,我使用了以下代码 @(Html.Telerik().Grid<State>() .Name("tlkStateGrid") .Columns(col => { col.Bound(m => m.CreatedOn).Title("Created On").Format("{0:dd/MM/yyyy}"); @(Html.T

我在Telerik MVC网格中有一列是DateTime类型的。我只想将它的日期部分用于显示和过滤。因此,我使用了以下代码

@(Html.Telerik().Grid<State>()
      .Name("tlkStateGrid")
      .Columns(col => {
          col.Bound(m => m.CreatedOn).Title("Created On").Format("{0:dd/MM/yyyy}");
@(Html.Telerik().Grid())
.Name(“tlkStateGrid”)
.列(列=>{
col.Bound(m=>m.CreatedOn).Title(“创建于”).Format(“{0:dd/MM/yyyy}”);
网格确实以指定的格式显示日期(CreatedOn)。但是,筛选没有按预期工作。我认为在筛选时,网格也会考虑时间值。因此,如果两个日期相同但时间值不同,则不认为它们“相等”。 如何配置网格以在筛选时忽略时间值而只比较日期


注意:我已经在Telerik MVC论坛上发布了类似的问题,但还没有答案。

您可以修改lambda表达式,将CreatedOn属性显式修改为仅仅是一个日期。您将只得到datetime对象的日期组件

col.Bound(m => m.CreatedOn.Date)
您的新代码将如下所示

@(Html.Telerik().Grid<State>()
      .Name("tlkStateGrid")
      .Columns(col => {
          col.Bound(m => m.CreatedOn.Date).Title("Created On").Format({0:dd/MM/yyyy}");

我创建了以下代码,更改了日期筛选器的定义方式:

/// <summary>
/// Maps DateTime related filters.
/// * IsEqualTo filter is converted to ('x-date' is GreaterThanOrEqualTo 'SearchDate') AND ('x-date' is LessThan 'SearchDate' + 1 Day)
/// * IsNotEqualTo filter is converted to ('x-date' LessThan 'SearchDate') OR ('x-date' is GreaterThan 'SearchDate' + 1 Day) OR ('x-date' is NULL)
/// * IsLessThanOrEqualTo filter is converted to ('x-date' is LessThan 'SearchDate' + 1 Day)
/// </summary>
/// <param name="copyOfOriginalFilters">A copy from the filters.</param>
/// <param name="newFilters">The new filters</param>
protected void MapDateFilter(ReadOnlyCollection<IFilterDescriptor> copyOfOriginalFilters, IList<IFilterDescriptor> newFilters)
{
    newFilters.Clear();

    foreach (var currentFilter in copyOfOriginalFilters)
    {
        Type t = currentFilter.GetType();

        if (t == typeof(FilterDescriptor))
        {
            var filter = currentFilter as FilterDescriptor;

            if (filter.ConvertedValue.GetType() == typeof(DateTime))
            {
                DateTime datePart = ((DateTime)filter.ConvertedValue).Date;

                if (filter.Operator == FilterOperator.IsEqualTo)
                {
                    var compositeFilter = new CompositeFilterDescriptor();
                    compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsGreaterThanOrEqualTo, datePart));
                    compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsLessThan, datePart.AddDays(1)));
                    compositeFilter.LogicalOperator = FilterCompositionLogicalOperator.And;

                    newFilters.Add(compositeFilter);
                }
                else if (filter.Operator == FilterOperator.IsNotEqualTo)
                {
                    var compositeFilter = new CompositeFilterDescriptor();
                    compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsLessThan, datePart));
                    compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsGreaterThan, datePart.AddDays(1)));
                    compositeFilter.FilterDescriptors.Add(new FilterDescriptor(filter.Member, FilterOperator.IsEqualTo, null));
                    compositeFilter.LogicalOperator = FilterCompositionLogicalOperator.Or;

                    newFilters.Add(compositeFilter);
                }
                else if (filter.Operator == FilterOperator.IsLessThanOrEqualTo)
                {
                    newFilters.Add(new FilterDescriptor(filter.Member, FilterOperator.IsLessThan, datePart.AddDays(1)));
                }
                else
                {
                    newFilters.Add(filter);
                }
            }
            else
            {
                newFilters.Add(filter);
            }
        }
        else if (t == typeof(CompositeFilterDescriptor))
        {
            var filter = currentFilter as CompositeFilterDescriptor;

            int numberOfDateFilters = filter.FilterDescriptors.Where(fd =>
                fd is FilterDescriptor &&
                (fd as FilterDescriptor).ConvertedValue != null &&
                (fd as FilterDescriptor).ConvertedValue.GetType() == typeof(DateTime))
                .Count();

            if (numberOfDateFilters == 2)
            {
                var firstFilter = filter.FilterDescriptors[0] as FilterDescriptor;
                firstFilter.Value = ((DateTime)firstFilter.ConvertedValue).Date;

                var secondFilter = filter.FilterDescriptors[1] as FilterDescriptor;
                secondFilter.Value = ((DateTime)secondFilter.ConvertedValue).Date;
            }
            else
            {
                MapDateFilter(new List<IFilterDescriptor>(filter.FilterDescriptors).AsReadOnly(), filter.FilterDescriptors);
            }

            newFilters.Add(filter);
        }
    }
}
//
///映射与日期时间相关的筛选器。
///*IsEqualTo筛选器转换为('x-date'大于或等于'SearchDate'),并且('x-date'小于'SearchDate'+1天)
///*IsNotEqualTo筛选器转换为('x-date'小于'SearchDate')或('x-date'大于'SearchDate'+1天)或('x-date'为空)
///*IsLessThanOrEqualTo筛选器转换为('x-date'小于'SearchDate'+1天)
/// 
///来自过滤器的副本。
///新过滤器
受保护的void MapDateFilter(原始筛选器的只读集合副本,IList newFilters)
{
newFilters.Clear();
foreach(原始过滤器副本中的var currentFilter)
{
类型t=currentFilter.GetType();
if(t==typeof(FilterDescriptor))
{
var filter=作为FilterDescriptor的currentFilter;
if(filter.ConvertedValue.GetType()==typeof(DateTime))
{
DateTime datePart=((DateTime)filter.ConvertedValue).Date;
if(filter.Operator==filterooperator.IsEqualTo)
{
var compositeFilter=新的CompositeFilterDescriptor();
compositeFilter.FilterDescriptors.Add(新的FilterDescriptor(filter.Member,FilterOperator.IsGreater大于OreQualto,datePart));
compositeFilter.FilterDescriptors.Add(新的FilterDescriptor(filter.Member,FilterOperator.IsLessThan,datePart.AddDays(1));
compositeFilter.LogicalOperator=过滤器组合逻辑运算符。和;
新增过滤器。添加(复合过滤器);
}
else if(filter.Operator==filterooperator.IsNotEqualTo)
{
var compositeFilter=新的CompositeFilterDescriptor();
添加(新的FilterDescriptor(filter.Member,FilterOperator.IsLessThan,datePart));
compositeFilter.FilterDescriptors.Add(新的FilterDescriptor(filter.Member,FilterOperator.IsgreetThan,datePart.AddDays(1));
添加(新的FilterDescriptor(filter.Member,FilterOperator.IsEqualTo,null));
compositeFilter.LogicalOperator=过滤器组合逻辑运算符。或;
新增过滤器。添加(复合过滤器);
}
else if(filter.Operator==FilterOperator.IsLessThanOrEqualTo)
{
newFilters.Add(newfilterDescriptor(filter.Member,FilterOperator.IsLessThan,datePart.AddDays(1));
}
其他的
{
新增过滤器。添加(过滤器);
}
}
其他的
{
新增过滤器。添加(过滤器);
}
}
else if(t==typeof(CompositeFilterDescriptor))
{
var filter=currentFilter作为CompositeFilterDescriptor;
int numberOfDateFilters=filter.FilterDescriptors.Where(fd=>
fd是过滤器描述器&&
(fd作为FilterDescriptor).ConvertedValue!=null&&
(fd作为FilterDescriptor).ConvertedValue.GetType()==typeof(DateTime))
.Count();
如果(numberOfDateFilters==2)
{
var firstFilter=filter.FilterDescriptors[0]作为FilterDescriptor;
值=((DateTime)firstFilter.ConvertedValue).Date;
var secondFilter=filter.FilterDescriptors[1]作为FilterDescriptor;
Value=((DateTime)secondFilter.ConvertedValue).Date;
}
其他的
{
MapDateFilter(新列表(filter.FilterDescriptors.AsReadOnly(),filter.FilterDescriptors);
}
新增过滤器。添加(过滤器);
}
}
}
这可以像这样使用:

protected void MapGridCommand(GridCommand command)
{
    this.MapDateFilter(new List<IFilterDescriptor>(command.FilterDescriptors).AsReadOnly(), command.FilterDescriptors);
}
protectedvoid MapGridCommand(GridCommand)
{
this.MapDateFilter(新列表(command.FilterDescriptors.AsReadOnly(),command.FilterDescriptors);
}

scartag,感谢您的回复。CreatedOn字段是可空的datetime,因此我按照您的建议使用col.Bound(m=>m.CreatedOn.Value.Date)。但是,我得到了“System.invalidoOperationException:可空对象必须有一个值”,当我尝试运行应用程序时。我最初也想过这样做,但Telerik网格不接受这种表达式。唯一允许的表达式是字段或属性访问表达式。因此,如果使用修改后的代码,我会得到“System.InvalidoOperationException:绑定列需要字段或属性访问表达式”@Nirvan也许你可以修改一下你的模型。如果你不想把事情搞砸的话,你可以用一个分部类来扩展它。然后添加一个新的属性CreatedOnDate,然后在那里使用这个表达式。这样你就可以使用CreatedOnDate fie了
protected void MapGridCommand(GridCommand command)
{
    this.MapDateFilter(new List<IFilterDescriptor>(command.FilterDescriptors).AsReadOnly(), command.FilterDescriptors);
}