基于Silverlight DataGrid中无代码设置开始与结束日期DatePicker的实现方法

下面给你详细讲解一下基于Silverlight DataGrid中无代码设置开始与结束日期DatePicker的实现方法的完整攻略。

问题概述

在Silverlight应用程序中使用DataGrid控件时,常常需要使用DatePicker控件来设置开始和结束日期筛选条件,但是如何无代码来实现这个功能呢?

解决方案

在Silverlight DataGrid控件中,如何无代码地设置开始和结束日期DatePicker控件,具体步骤如下:

步骤一

首先,在XAML中添加开始日期和结束日期的DatePicker控件:

<StackPanel Orientation="Vertical">
    <DatePicker x:Name="datePickerStart" Width="120" Margin="10,5" SelectedDate="{Binding StartDate, Mode=TwoWay}" />
    <DatePicker x:Name="datePickerEnd" Width="120" Margin="10,5" SelectedDate="{Binding EndDate, Mode=TwoWay}" />
</StackPanel>

步骤二

然后,在DataGrid的样式中添加样式后台代码:

<DataGrid.Resources>
    <Style TargetType="sdk:DataGridColumnHeader">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="sdk:DataGridColumnHeader">
                    <Grid x:Name="Root" Background="{TemplateBinding Background}">
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <ContentPresenter 
                            Grid.Row="0" 
                            Grid.Column="0" 
                            Content="{TemplateBinding Content}" 
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                        <ComboBox 
                            x:Name="cmbFilter" 
                            Grid.Row="0" 
                            Grid.Column="1" 
                            ItemsSource="{Binding DataContext.FilterableFields, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=sdk:DataGrid}}"
                            SelectedItem="{Binding FilterField}"
                            VerticalAlignment="Center" 
                            Width="120"/>
                        <StackPanel 
                            x:Name="stackDates" 
                            Grid.Row="1" 
                            Grid.Column="0" 
                            Grid.ColumnSpan="2" 
                            Orientation="Horizontal" 
                            HorizontalAlignment="Center"
                            Visibility="{Binding FilterVisibility}">
                            <TextBlock 
                                x:Name="txtFromDate" 
                                HorizontalAlignment="Center" 
                                Margin="3,0,3,0" 
                                Text="FromDate"/>
                            <sdk:DatePicker 
                                x:Name="datePickerStart" 
                                SelectedDate="{Binding StartDate, Mode=TwoWay}" 
                                Width="120"/>
                            <TextBlock 
                                x:Name="txtToDate" 
                                HorizontalAlignment="Center" 
                                Margin="3,0,3,0" 
                                Text="ToDate"/>
                            <sdk:DatePicker 
                                x:Name="datePickerEnd" 
                                SelectedDate="{Binding EndDate, Mode=TwoWay}" 
                                Width="120"/>
                        </StackPanel>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.Resources>

示例

下面分别给出两个示例,来说明如何在Silverlight DataGrid中无代码设置开始和结束日期DatePicker控件:

示例一:绑定列表数据

假设我们有一个列表数据,我们需要在列表的标题行中添加开始和结束日期的筛选控件。在实现这个需求时,我们需要在数据模型类中添加StartDate和EndDate属性,并继承IEditableObject接口:

public class MyDataItem : IEditableObject
{
    public string Name { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    // IEditableObject 接口方法实现
    public void BeginEdit()
    {
        // 实现备份操作
    }

    public void CancelEdit()
    {
        // 实现恢复备份操作
    }

    public void EndEdit()
    {
        // 不需要实现,因为 Silverlight 的数据绑定框架会自动提交
    }
}

然后,我们需要使用ObservableCollection作为DataGrid的数据源,并且为DataGrid控件的FilterableFields属性添加绑定成功的事件处理程序:

<sdk:DataGrid 
    x:Name="dataGrid" 
    ItemsSource="{Binding MyDataItems}" 
    AutoGenerateColumns="False"
    IsReadOnly="True" 
    LoadingRow="DataGrid_LoadingRow" 
    ScrollViewer.VerticalScrollBarVisibility="Auto" 
    ScrollViewer.HorizontalScrollBarVisibility="Auto"
    FilterableFields="{Binding FilterableFields, Mode=OneWay, NotifyOnTargetUpdated=True}" 
    TargetUpdated="DataGrid_TargetUpdated">
</sdk:DataGrid>

在事件处理程序中,我们需要初始化FilterableFields属性的值,并设置DataContext对象的FilterVisibility属性的值:

private void DataGrid_TargetUpdated(object sender, DataTransferEventArgs e)
{
    // 初始化 FilterableFields 属性
    foreach (var prop in typeof(MyDataItem).GetProperties())
    {
        var att = prop.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault() as DisplayAttribute;
        var name = att != null && !string.IsNullOrEmpty(att.Name) ? att.Name : prop.Name;
        FilterableFields.Add(name);
    }

    // 设置 FilterVisibility 属性
    if (FilterableFields.Count > 0)
    {
        var header = (sdk:DataGridColumnHeader)e.TargetObject;
        var ctx = header.DataContext as MyDataListViewModel;
        var fi = ctx.GetType().GetProperty("FilterVisibility");
        if (fi != null)
        {
            var value = Visibility.Collapsed;
            var fields = ctx.GetType().GetProperty("FilterableFields").GetValue(ctx, null) as List<string>;
            if (fields != null && fields.Contains(header.Content.ToString()))
            {
                value = Visibility.Visible;
            }

            fi.SetValue(ctx, value, null);
        }
    }
}

此时,我们已经完成了Silverlight DataGrid中的无代码设置开始和结束日期DatePicker控件的实现。我们可以在代码中使用下面这样的方式来绑定筛选条件:

CollectionViewSource.GetDefaultView(MyDataItems).Filter = new Predicate<object>(item =>
{
    var i = (MyDataItem)item;

    // 开始日期筛选条件
    if (StartDate.HasValue)
    {
        if (i.StartDate < StartDate.Value)
        {
            return false;
        }
    }

    // 结束日期筛选条件
    if (EndDate.HasValue)
    {
        if (i.EndDate > EndDate.Value)
        {
            return false;
        }
    }

    // 其它筛选条件
    ...
    return true;
});

示例二:手动添加列

如果我们手动添加列,我们需要在列头控件的Loaded事件处理程序中添加DatePicker控件:

<sdk:DataGrid x:Name="dataGrid" ItemsSource="{Binding MyDataItems}" AutoGenerateColumns="False" IsReadOnly="True">
    <sdk:DataGrid.Columns>
        <sdk:DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
        <sdk:DataGridTemplateColumn>
            <sdk:DataGridTemplateColumn.Header>
                <StackPanel>
                    <TextBlock Text="Start Date"/>
                    <DatePicker x:Name="datePickerStart" SelectedDate="{Binding StartDate, Mode=TwoWay}"/>
                </StackPanel>
            </sdk:DataGridTemplateColumn.Header>
            <sdk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding StartDate, StringFormat='{}{0:yyyy-MM-dd}'}"/>
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellTemplate>
        </sdk:DataGridTemplateColumn>
        <sdk:DataGridTemplateColumn>
            <sdk:DataGridTemplateColumn.Header>
                <StackPanel>
                    <TextBlock Text="End Date"/>
                    <sdk:DatePicker x:Name="datePickerEnd" SelectedDate="{Binding EndDate, Mode=TwoWay}"/>
                </StackPanel>
            </sdk:DataGridTemplateColumn.Header>
            <sdk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding EndDate, StringFormat='{}{0:yyyy-MM-dd}'}"/>
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellTemplate>
        </sdk:DataGridTemplateColumn>
    </sdk:DataGrid.Columns>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding DataContext.InitializeCommand, ElementName=dataGrid}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</sdk:DataGrid>

在代码中,我们需要添加以下命令来初始化列头中的DatePicker控件:

public ICommand InitializeCommand
{
    get
    {
        if (_initializeCommand == null)
        {
            _initializeCommand = new RelayCommand(Initialize);
        }
        return _initializeCommand;
    }
}

private void Initialize()
{
    var headerStart = dataGrid.Columns[1].Header as StackPanel;
    if (headerStart != null)
    {
        var datePickerStart = headerStart.Children[1] as DatePicker;
        if (datePickerStart != null)
        {
            datePickerStart.SetValue(DatePicker.SelectedDateProperty, StartDate);
        }
    }

    var headerEnd = dataGrid.Columns[2].Header as StackPanel;
    if (headerEnd != null)
    {
        var datePickerEnd = headerEnd.Children[1] as DatePicker;
        if (datePickerEnd != null)
        {
            datePickerEnd.SetValue(DatePicker.SelectedDateProperty, EndDate);
        }
    }
}

此时,我们已经完成了Silverlight DataGrid中的无代码设置开始和结束日期DatePicker控件的实现。我们可以在代码中使用下面这样的方式来绑定筛选条件:

CollectionViewSource.GetDefaultView(MyDataItems).Filter = new Predicate<object>(item =>
{
    var i = (MyDataItem)item;

    // 开始日期筛选条件
    if (StartDate.HasValue)
    {
        if (i.StartDate < StartDate.Value)
        {
            return false;
        }
    }

    // 结束日期筛选条件
    if (EndDate.HasValue)
    {
        if (i.EndDate > EndDate.Value)
        {
            return false;
        }
    }

    // 其它筛选条件
    ...
    return true;
});

至此,两个示例都已经完成了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于Silverlight DataGrid中无代码设置开始与结束日期DatePicker的实现方法 - Python技术站

(0)
上一篇 2023年6月1日
下一篇 2023年6月1日

相关文章

  • Unity通过代码修改按钮点击效果

    下面我将为您详细讲解Unity通过代码修改按钮点击效果的完整攻略,包含两条示例说明。 一、Unity通过代码修改按钮点击效果的步骤 1.创建UI按钮 首先,在Unity中创建一个UI按钮。具体步骤:GameObject -> UI -> Button。 2.添加响应代码 选中按钮,进入Inspector面板,在“On Click()”中点击”+”…

    C# 2023年6月3日
    00
  • C#生成指定范围内的不重复随机数

    下面是” C#生成指定范围内的不重复随机数 “的攻略。 1. 使用 C# 的 Random 类生成随机数 System.Random 是 C# 中封装了随机数生成器的类,可以用来生成伪随机数。Random 的默认构造函数可以产生种子数,可以在每次生成随机数时用来确定这个随机数系列的起始位置,从而产生不同的随机数序列。 2. 生成指定范围内的随机数 生成指定范…

    C# 2023年6月7日
    00
  • Entity Framework Core相关包的概念介绍与安装

    下面详细给您介绍一下”Entity Framework Core相关包的概念介绍与安装”的完整攻略。 什么是Entity Framework Core? Entity Framework Core是一个全新的对象关系映射框架,支持.NET Core平台,使用C#语言实现。它能够使开发人员通过操作对象来进行数据库操作,而不是直接使用SQL命令。它具有灵活性和可…

    C# 2023年5月31日
    00
  • C# 数组中的 indexOf 方法及使用

    C# 数组中的 indexOf 方法及使用 在C#中,数组是一种非常常见的数据结构,它们可以用来存储多个相同类型的数据。我们可以使用indexOf方法来查找指定元素在数组中的索引位置。 indexOf 方法的语法 indexOf方法用于查找数组中指定元素的位置,语法如下: public static int indexOf(Object[] array, O…

    C# 2023年6月7日
    00
  • c#中值类型和引用类型的基础教程

    下面是关于“c#中值类型和引用类型的基础教程”的完整攻略: 概述 在C#中,变量可以分为两种类型:值类型和引用类型。这两种类型在内存中有不同的处理方式,因此在使用时需注意它们之间的差异。 值类型 值类型的变量直接存储其值,这意味着它们被存储在程序的栈中。栈内存是一种自动分配和释放的内存,通常用于存储函数参数和局部变量等短期数据。 C#中有多种内置的值类型,如…

    C# 2023年6月1日
    00
  • C# 超高面试题收集整理

    C# 超高面试题收集整理攻略 收集面试题 了解常见的C#面试题类型,包括但不限于:基础语法、数据类型、控制语句、循环结构、集合、类与对象、继承、多态、接口、委托与事件、异常处理、LINQ等。 搜集各种面试题资源,可从面试题网站、CSDN等博客、GitHub等代码仓库、书籍、视频等渠道获取。 将获取到的面试题资源整理成相应类型的文档,方便后续的整理、学习。 整…

    C# 2023年6月3日
    00
  • C#将图片存放到SQL SERVER数据库中的方法

    前言 在开发过程中,我们通常需要将图片等二进制数据存储到数据库中,方便管理和备份。本文将介绍使用C#将图片存储到SQL SERVER数据库中的方法,包括以下几个方面: 创建数据库表格 读取本地图片 将图片转换为字节数组 将字节数组保存到数据库中 创建数据库表格 在SQL SERVER中创建一个名为Images的表格,用于存储图片数据。该表格包含三个字段: I…

    C# 2023年6月2日
    00
  • C#实现简单获取及设置Session类

    下面就是有关“C#实现简单获取及设置Session类”的详细攻略。 1. Session类的简介 ASP.NET Session对象是服务器端用来保存当前用户会话所需要的信息的一个对象,它的使用可以让我们在多个页面中共享数据,并且在不同的请求之间保持数据的一致性。Session类的主要作用有两个:一是用来存储用户端与服务器端会话信息,二是用来跟踪用户在整个网…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部