【问题标题】:Show calendar in Ultragrid Column Filter在 Ultragrid 列过滤器中显示日历
【发布时间】:2013-07-30 09:51:50
【问题描述】:

我有一个 UltraGrid,其中有很多列,其中 2 列是 DateTime 样式。现在,当我使用该列的过滤器时,它会将所有 DateTime 值显示为下拉列表中的文本。但我需要它作为日历,以使过滤器变得容易。单击过滤器时只显示一个日历就足够了。

我尝试了一些代码,但它不起作用。

//代码:

Private Sub grdResult_BeforeRowFilterDropDown(ByVal sender As Object, ByVal e As Infragistics.Win.UltraWinGrid.BeforeRowFilterDropDownEventArgs) Handles grdResult.BeforeRowFilterDropDown
                e.Cancel = True
                UltraCalendarCombo1.Visible = True
               UltraCalendarCombo1.Location = New Point(grdResult.Rows.FilterRow.Cells(e.Column).GetUIElement().Rect.Location.X, grdResult.Rows.FilterRow.Cells(e.Column).GetUIElement().Rect.Location.Y - 2)
                UltraCalendarCombo1.Size = New System.Drawing.Size(grdResult.Rows.FilterRow.Cells(e.Column).GetUIElement().Rect.Size.Width, grdResult.Rows.FilterRow.Cells(e.Column).GetUIElement().Rect.Size.Height)
                ' UltraCalendarCombo1.DroppedDown = True

            End Sub

点击过滤器下拉菜单时会触发上述事件。

    private sub applyCustomeViewSettings(byval gridFormat as GridFormat)
    ....
    ...
       For Each ColumnFormat In gridFormat.ColumnFormats

                    For Each column In Me.grdResult.DisplayLayout.Bands(0).Columns

                        If column.Key.ToUpper = ColumnFormat.ColumnKey.ToUpper Then
                            If column.Key.ToUpper = "PCSSTDT" Then
                                column.Header.Caption = IIf(ColumnFormat.Caption = "", ColumnFormat.ColumnKey, ColumnFormat.Caption)
                                column.Hidden = ColumnFormat.Hidden
                                'column.AllowRowFiltering = IIf(ColumnFormat.AllowRowFiltering = False, ColumnFormat.AllowRowFiltering, DefaultableBoolean.True) 'CType(ColumnFormat.AllowRowFiltering, DefaultableBoolean)
                                column.Width = ColumnFormat.Width
                                column.Header.VisiblePosition = ColumnFormat.VisiblePosition
                                column.Format = ColumnFormat.Format
                                column.SortIndicator = ColumnFormat.SortIndicator
                                ' column.Style = ColumnStyle.Date
                                'column.EditorComponent = UltraCalendarCombo1
                                column.FilterOperandStyle = FilterOperandStyle.Default

                            Else
                                column.Header.Caption = IIf(ColumnFormat.Caption = "", ColumnFormat.ColumnKey, ColumnFormat.Caption)
                                column.Hidden = ColumnFormat.Hidden
                                column.AllowRowFiltering = IIf(ColumnFormat.AllowRowFiltering = False, ColumnFormat.AllowRowFiltering, DefaultableBoolean.True) 'CType(ColumnFormat.AllowRowFiltering, DefaultableBoolean)
                                column.Width = ColumnFormat.Width
                                column.Header.VisiblePosition = ColumnFormat.VisiblePosition
                                column.Format = ColumnFormat.Format
                                column.SortIndicator = ColumnFormat.SortIndicator
                                column.Style = ColumnFormat.Style
                            End If
                        End If

                    Next
    ....
    ...

    End Sub

上述方法使网格更改(应用设置)以将过滤器显示为日历。 但这不起作用并显示相同的正常网格。

我怎样才能做到这一点?

【问题讨论】:

  • 让我更好地理解,您想单击数据时间列标题中的过滤器图标。您想要显示一个日历,而不是日期列表,用户从中选择一个日期,然后您使用所选数据过滤网格?还有您的列中不存在的日期?
  • @Steve:感谢您的回复。只需包含所有日期的日历就足够了。当用户在日历中选择的日期与网格中的日期列表不匹配时,网格应该为空。问题是当用户单击网格的 DateTime 列过滤器时应该显示日历。

标签: vb.net infragistics ultrawingrid


【解决方案1】:

当您按图标过滤 UltraWinGrid 中的 DateTime 列时,我已成功显示 MonthCalendar
当显示MonthCalendar 时,您可以使用此标准 WinForm 控件提供的熟悉界面选择特定日期。选择日期后,您可以使用该值以编程方式将过滤条件应用于 UltraWinGrid 列。

要达到此结果,您首先需要添加对 Infragistics4.Win.SupportsDialog.v11.2 程序集的引用,您可以在其中找到 UltraGridFilterUIProvider

现在,在您需要过滤出现的表单中,添加以下代码:(这只是一个示例,因为我没有您的数据源,因此我有一个只有一个日期时间列的预构建数据源)

Imports Infragistics.Win.UltraWinGrid
Imports Infragistics.Win.SupportDialogs.FilterUIProvider

Public Class Form1
    ' This is the key object that let us customize ' 
    ' the Filter for the UltraWinGrid'
    Dim _filterUIProvider as UltraGridFilterUIProvider

    ' In the InitializeLayout event we substitute the normal 
    ' filter handler with the custom filter'
    Private Sub UltraGrid1_InitializeLayout(sender As Object, e As Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs) Handles UltraGrid1.InitializeLayout

        e.Layout.Override.AllowRowFiltering = Infragistics.Win.DefaultableBoolean.True
        _filterUIProvider = New UltraGridFilterUIProvider()

        ' Comment out the following line to test the default 
        ' **Excel Filter Style Interface** '
        AddHandler _filterUIProvider.BeforeMenuPopulate, AddressOf _filterUIProvider_BeforeMenuPopulate
        e.Layout.Override.FilterUIProvider = _filterUIProvider
    End Sub

    ' Before the UltraGridFilterUIProvider shows its standard form interface 
    ' we start a custom form  used to apply our filtering logic '
    ' and block the display of the UltraGridFilterUIProvider interface '
    Private Sub _filterUIProvider_BeforeMenuPopulate(sender As Object, e As Infragistics.Win.SupportDialogs.FilterUIProvider.BeforeMenuPopulateEventArgs)

        ' A custom form with the MonthCalendar and 3 buttons '
        ' to handle the filter logic '
        Using fDate = new FormDate() 

            ' Open our custom form with the monthcalendar
            if (DialogResult.OK = fDate.ShowDialog())  

                ' We need a nullable date to allow the removing of the filter'
                Dim dtFilter As DateTime? = fDate.SelectedDate
                if (dtFilter.HasValue)

                    ' Apply programmatically a filtercondition to the column 
                    ' In this case I have only one column. so I use the index 0
                    ' in your case this should change to reflect your column index
                    Dim fc = new FilterCondition(FilterComparisionOperator.Equals, dtFilter.Value)
                    ultraGrid1.DisplayLayout.Bands(0).ColumnFilters(0).FilterConditions.Add(fc)

                Else
                    ultraGrid1.DisplayLayout.Bands(0).ColumnFilters.ClearAllFilters()
                End If
            End If
        End Using
        e.Handled = true ' Stop the standard interface'
    End Sub
End Class

现在我们只需要一个名为 FormDate 的简单表单,它包含一个 MonthCalendar 和三个按钮(Set、Clear、Cancel),它们返回(Set)一个 Date 来设置过滤器,(Clear)一个 null删除先前过滤器的值和中止处理的取消按钮

这里是表单的代码,设计很简单

Public Class FormDate
    Public Property SelectedDate As DateTime?

    Private Sub FormDate_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.SelectedDate = Nothing
    End Sub

    Private Sub cmdSet_Click(sender As Object, e As EventArgs) Handles cmdSet.Click
        'This button has DialogResult=OK'
        Me.SelectedDate = monthCalendar1.SelectionStart
    End Sub

    Private Sub cmdClear_Click(sender As Object, e As EventArgs) Handles cmdClear.Click
        'This button has DialogResult=OK'
        Me.SelectedDate = Nothing
    End Sub
End Class

这可以解决您的问题,但是,我发现 UltraGridFilterUIProvider 中似乎存在错误。当我调用 e.Handled=True 时,我的预期结果是过滤器不显示任何内容,而是仍然出现一个小窗口,我必须按 Escape 将其隐藏。我还没有找到任何自动隐藏它的方法。
向 Infragistics 团队发出信号似乎是个问题。

我建议你也测试一下 UltraGridFilterUIProvider 自动提供的 Excel Style Filter Interface。这个界面有很多选项,比标准的 UI 过滤器更可取。要测试这个接口,你应该只注释掉上面的 AddHandler 行

编辑 根据@Alhalama 的评论,我尝试使用 BeforeRowFilterDropDown 事件,结果更好(现在很完美)。所以我用 AddHandler 注释掉了这一行,删除了 BeforeMenuPopulate 的代码并添加了 BeforeRowFilterDropDown 的代码

Private Sub UltraGrid1_BeforeRowFilterDropDown(sender As Object, e As BeforeRowFilterDropDownEventArgs) Handles UltraGrid1.BeforeRowFilterDropDown
    If e.Column.Key = "DateRequest" Then
        Using fDate = New FormDate()
            If DialogResult.OK = fDate.ShowDialog() Then
                Dim dtFilter As DateTime? = fDate.SelectedDate
                If (dtFilter.HasValue) Then
                    Dim fc As FilterCondition = New FilterCondition(FilterComparisionOperator.Equals, dtFilter.Value)
                    UltraGrid1.DisplayLayout.Bands(0).ColumnFilters(0).FilterConditions.Add(fc)
                Else
                    UltraGrid1.DisplayLayout.Bands(0).ColumnFilters.ClearAllFilters()
                End If
            End If
        End Using
        e.Cancel = True
    End If
End Sub

现在,当我尝试为名为 DateRequest 的列打开过滤器时,我立即打开 FormDate,最后我将 BeforeRowFilterDropDownEventArgs 的 Cancel 属性设置为 true 以避免进一步处理过滤器对话。这似乎是完美的……这要归功于 Alhalama 先生。如果您愿意,我认为您应该发布自己的答案,因为您的建议确实有所作为。

【讨论】:

  • 非常感谢史蒂夫。我能知道在哪里下载 Infragistics4.Win.SupportsDialog.v11.2 dll 吗?
  • 这是一个包含在 NetAdvantage Suite 中的程序集。您应该已经拥有它,也许在不同的版本中,但我认为功能应该是相同的。查看您的引用对话框并搜索它。
  • @Steve 在 BeforeMenuPopulate 事件上将 e.Handled 设置为 True 不会阻止显示过滤器菜单。 API 文档中有更多详细信息:help.infragistics.com/NetAdvantage/WinForms/Current/CLR4.0/…
  • @Steve 由于您提供自己的对话框并手动添加 FilterCondition,因此您可能只想处理网格的 BeforeRowFilterDropDown 事件并在它是编辑日期时间的列时取消它。有关 BeforeRowFilterDropDown 事件的更多信息:help.infragistics.com/NetAdvantage/WinForms/Current/CLR4.0/…
  • @alhalama 我明白了,它仅用于停止添加菜单项。你知道一种自动关闭空窗口的方法吗?无论如何感谢您的关注
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2022-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多