Completed
Last Updated: 02 Nov 2017 10:49 by ADMIN
ADMIN
Hristo
Created on: 27 Oct 2017 09:50
Category: UI Framework
Type: Bug Report
1
FIX. RadControl - avoid multiple scaling in High DPI when setting the MinimumSize or MaximumSize properties
How to reproduce: set the MinimumSize property of a RadButton in a DPI-aware app
Workaround: 
Public Class RadForm1
    Dim minMaxStack = New Stack(Of Dictionary(Of Control, Tuple(Of Size, Size)))()

    Sub New()
        InitializeComponent()
    End Sub

    Protected Overrides Sub HandleDpiChanged()

        Dim scaleFactor As Single = 1.0F
        Dim oldDpi = GetType(RadFormControlBase).GetField("oldDpi", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me)
        Dim currentDpi = GetType(RadFormControlBase).GetField("currentDpi", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me)

        If oldDpi <> 0 Then
            scaleFactor = CSng(currentDpi) / oldDpi
        ElseIf oldDpi = 0 Then
            scaleFactor = CSng(currentDpi) / 96.0F
        End If

        If scaleFactor = 1.0F Then
            Return
        End If

        Me.SaveMinMaxStates()
        MyBase.HandleDpiChanged()
        Me.RestoreMinMaxStates()

    End Sub

    Private Sub SaveMinMaxStates()
        If Me.minMaxStack Is Nothing Then
            Me.minMaxStack = New Stack(Of Dictionary(Of Control, Tuple(Of Size, Size)))()
        End If

        Dim minMax As New Dictionary(Of Control, Tuple(Of Size, Size))()
        Dim queue As New Queue(Of Control)()

        For Each ctrl As Control In Me.Controls
            queue.Enqueue(ctrl)
        Next

        While queue.Count > 0
            Dim ctrl As Control = queue.Dequeue()
            If TypeOf ctrl Is RadControl Then
                minMax.Add(ctrl, New Tuple(Of Size, Size)(ctrl.MinimumSize, ctrl.MaximumSize))
                ctrl.MinimumSize = Size.Empty
                ctrl.MaximumSize = Size.Empty
            End If

            For Each childControl As Control In ctrl.Controls
                queue.Enqueue(childControl)
            Next
        End While

        Me.minMaxStack.Push(minMax)
    End Sub

    Private Sub RestoreMinMaxStates()
        Dim minMax As Dictionary(Of Control, Tuple(Of Size, Size)) = Me.minMaxStack.Pop()
        Dim queue As New Queue(Of Control)()

        For Each ctrl As Control In Me.Controls
            queue.Enqueue(ctrl)
        Next

        While queue.Count > 0
            Dim ctrl As Control = queue.Dequeue()

            If minMax.ContainsKey(ctrl) Then
                ctrl.MinimumSize = minMax(ctrl).Item1
                ctrl.MaximumSize = minMax(ctrl).Item2
                minMax.Remove(ctrl)
            End If

            For Each childControl As Control In ctrl.Controls
                queue.Enqueue(childControl)
            Next
        End While

        minMax.Clear()
    End Sub
End Class
0 comments