Custom DayButtonStyle overriden when reducing columns

8 posts, 0 answers
  1. Daniel
    Daniel avatar
    5 posts
    Member since:
    Jul 2014

    Posted 13 May Link to this post

    A peculiar behavior we have found with the RadCalendar control:

    We have a custom DayButtonStyleSelector set to an instance of a RadCalendar. This StyleSelector sets the Visibility of days that do not belong to the month displayed as Collapsed, instead of being grayed out as they normally would be.

    Furthermore, we dynamically change the number of columns displayed dependent on the width available to the RadCalendar.

    The StyleSelector works as intended when loading the Calendar and when increasing the column count, but when we reduce the column count by reducing the space available for the RadCalendar control, the last column seems to ignore the StyleSelector and displays the days of the following month in grey.

    However, using Snoop we found out that the Style is applied - and consequently overridden by a locally set Visibility.

    This only happens for the last column, and only when reducing the number of columns. Please see the attached screenshots (1.jpg shows the Calendar after loading, 2.jpg shows the calendar after expanding enough to display a third column, 3.jpg shows the calendar after reducing it back to 2 columns).

    A code sample to illustrate this problem:

     

    <Window x:Class="MainWindow"
           Title="MainWindow" Height="200" Width="400">
        <telerik:RadCalendar VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Name="cal" />
    </Window>

     

    And the code behind (please excuse the VB.Net):

     

    Imports Telerik.Windows.Controls.Calendar
    Class MainWindow
        Private Const MinCalendarWidth = 150
        Public Sub New()
            ' This call is required by the designer.
            InitializeComponent()
            ' Add any initialization after the InitializeComponent() call.
            cal.DayButtonStyle = Nothing
            cal.DayButtonStyleSelector = New CDayStyleSelector()
        End Sub
        Protected Overrides Sub OnRenderSizeChanged(sizeInfo As SizeChangedInfo)
            MyBase.OnRenderSizeChanged(sizeInfo)
            Dim CalendarColumns = Math.Max(1, CInt(Math.Floor(sizeInfo.NewSize.Width / MinCalendarWidth)))
            If cal.Columns <> CalendarColumns Then
                cal.Columns = CalendarColumns
            End If
        End Sub
        Private Class CDayStyleSelector
            Inherits StyleSelector
            Private _HideButtonStyle As New Style
            Public Sub New()
                _HideButtonStyle.Setters.Add(New Setter(VisibilityProperty, Visibility.Collapsed))
            End Sub
            Public Overrides Function SelectStyle(item As Object, container As DependencyObject) As Style
                Dim Content = TryCast(item, CalendarButtonContent)
                If Content IsNot Nothing AndAlso Content.ButtonType = CalendarButtonType.Date Then
                    If Not Content.IsFromCurrentView OrElse Content.IsInAnotherView Then
                        Return _HideButtonStyle 'Hide all Buttons of other months
                    End If
                End If
                Return MyBase.SelectStyle(item, container)
            End Function
        End Class
    End Class

     

    You can observe the problem described by changing the width of the window.

  2. Kalin
    Admin
    Kalin avatar
    1208 posts

    Posted 17 May Link to this post

    Hello Daniel,

    I tested the explained scenario, however didn't observe any issues. Can you please check the attached sample project and let me know if I have missed anything there? Also can you share the version of the control you are using?

    I'm looking forward to hearing from you.

    Regards,
    Kalin
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Daniel
    Daniel avatar
    5 posts
    Member since:
    Jul 2014

    Posted 17 May Link to this post

    Hello Kalin,

    Yes, I am afraid you have missed an integral part. As mentioned in the original post, we dynamically change the number of calendars displayed by setting the Column property of the RadCalendar. This is done in the OnRenderSizeChanged override in the MainWindow code-behind. When I insert the following code (a direct translation from the VB.Net code in the original post) into your example project, the problem shows itself again (when you increase and then decrease the window width via the mouse cursor):

    protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
    {
        base.OnRenderSizeChanged(sizeInfo);
        var calenderColumns = Math.Max(1, (int)Math.Floor(sizeInfo.NewSize.Width / minCalendarWidth));
        if(cal.Columns != calenderColumns)
        {
            cal.Columns = calenderColumns;
        }
    }

     

    We are using the current version of the Telerik controls, i.e. 2016.2.503.40.

  5. Daniel
    Daniel avatar
    5 posts
    Member since:
    Jul 2014

    Posted 17 May in reply to Daniel Link to this post

    I forgot to mention: This code also uses the minCalendarWidth member variable set in the MainWindow. You can either insert it, or replace the reference to minCalendarWidth with its value, 150.

     

  6. Kalin
    Admin
    Kalin avatar
    1208 posts

    Posted 20 May Link to this post

    Hello Daniel,

    Thanks for the additional details, we managed to reproduce the observed behavior. However we will need some more time to further investigate. Meanwhile what I can suggest you would be instead of Visibility to set change the Opacity and set IsHitTestVisible to false and will work as expected:

    public CustomDayButtonStyleSelector()
    {
        this.HideButtonStyleSelector = new Style() { TargetType = typeof(CalendarButton) };
        this.HideButtonStyleSelector.Setters.Add(new Setter(FrameworkElement.OpacityProperty, 0d));
        this.HideButtonStyleSelector.Setters.Add(new Setter(FrameworkElement.IsHitTestVisibleProperty, false));
    }

    Hope this helps.

    Regards,
    Kalin
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  7. Daniel
    Daniel avatar
    5 posts
    Member since:
    Jul 2014

    Posted 20 May in reply to Kalin Link to this post

    Hello Kalin,

    Thank you. Your workaround seems to work. Would it be possible to be informed about a fix, should the behaviour described in the original post be fixed?

  8. Kalin
    Admin
    Kalin avatar
    1208 posts

    Posted 25 May Link to this post

    Hi Daniel,

    We are currently investigating the cause of the observed behavior. I will get back to you with more details as soon as possible.

    Regards,
    Kalin
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  9. Kalin
    Admin
    Kalin avatar
    1208 posts

    Posted 30 May Link to this post

    Hi Daniel,

    Thanks for your patience.

    Due to the implementation of the control, the Visibility of the CalendarButtons is being toggled in specific cases. So when the Visibility is explicitly set the setter from the Style is being ignored from the framework. However this scenario has an easy solution - just clear previous value before applying the collapsed style and everything will work as expected:

    if (!content.IsFromCurrentView || content.IsInAnotherView)
    {
        container.ClearValue(UIElement.VisibilityProperty);
        return this.HideButtonStyleSelector;
    }

    Hope this helps. If you have any other questions, let us know.

    Regards,
    Kalin
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Back to Top
UI for WPF is Visual Studio 2017 Ready