在Ultragrid列过滤器中显示日历

问题描述:

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

I have an UltraGrid in which I have many columns of which 2 columns are DateTime style. Now when I use the filter of that columns it shows all the DateTime values as a text in a dropdown. But I need that as a calendar in order to make the filter easy. It is enough to show just a calendar when clicking the filter.

我尝试了一些代码,但是没有用.

I have tried some code but it doesn't work.

//代码:

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

点击过滤器下拉菜单时,将触发上述事件.

The above event will fire when the filter dropdown is clicked.

    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

以上方法使网格发生变化(应用设置)以将过滤器显示为日历. 但这不起作用,并向我显示相同的普通网格.

The above method makes the grid changes(apply settings) to show the filter as calendar. But this doesn't work and showing me the same normal grid.

我该如何实现?

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

I have managed to show a MonthCalendar when you press the icon to filter a DateTime column in an UltraWinGrid.
When the MonthCalendar is dispayed you could select a specific date using the familiar interface provided by this standard WinForm control. After selecting the date you could use the value to apply programmatically a filter condition to the UltraWinGrid column.

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

To reach this result you first need to add a reference to the Infragistics4.Win.SupportsDialog.v11.2 assembly where you can find the UltraGridFilterUIProvider class

现在,在您需要过滤显示的表单中,添加以下代码:(这只是一个示例,因为我没有您的数据源,因此我有一个只有一个datetime列的预制数据源)

Now, in your form where you need the filtering to appear, add this code: (it is just an example because I haven't your datasource and thus I have a prebuilt one with just one datetime column)

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和三个按钮(设置",清除",取消"),它们会返回(设置")一个日期以设置过滤器,(清除")一个null值以删除先前的过滤器,并单击取消按钮中止处理

Now we need only a simple form called FormDate that contains a MonthCalendar and three buttons (Set, Clear, Cancel) that return (Set) a Date to set the filter, (Clear) a null value to remove previous filter and a cancel button to abort the processing

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

Here the code for the form, the design is trivial

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团队发出信号似乎是一个问题.

This could resolve your problem, however, I have discoverd what seems to be a bug in UltraGridFilterUIProvider. When I call the e.Handled=True my expected result is the filter to not show anything but, instead a small window still appears and I have to press Escape to hide it. I have not found any way to automatically hide it.
It seems to be a problem to signal to the Infragistics team.

我建议您还测试UltraGridFilterUIProvider自动提供的 Excel样式过滤器界面.此界面有很多选项,比标准的UI筛选器更可取.要测试此接口,您只应注释掉上面的AddHandler行

I suggest you also to test the Excel Style Filter Interface provided automatically by the UltraGridFilterUIProvider. This interface has a lot of options and is much more preferable to the standard UI filter. To test this interface you should only comment out the AddHandler line above

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

EDIT Following the comment from @Alhalama I have tried to use the BeforeRowFilterDropDown event and the result are better (well it is perfect now). So I have commented out the line with the AddHandler, removed the code for the BeforeMenuPopulate and added the code for the 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先生对此深表感谢.如果您愿意,我认为您应该发表自己的答案,因为您的建议确实有所作为.

Now, when I try to open the filter for the column named DateRequest I open immediately the FormDate and at the end I set the Cancel property of the BeforeRowFilterDropDownEventArgs to true to avoid further processing of the filter dialog. This seems to be perfect...... Great credit for this to Mr. Alhalama. If you wish I think you should post your own answer because your suggestion really makes the difference.