leocb / MaterialSkin

Theming .NET WinForms, C# or VB.Net, to Google's Material Design Principles.
MIT License
428 stars 130 forks source link

strange behavior in redraw #357

Open merco opened 2 years ago

merco commented 2 years ago

I have a form with materialcard, materialcombo and materialcheck. It is normally shown correctly.

immagine

In some cases (I did not understand when) the mask appears "not redrawn" correctly: for example the checkboxes have no dot and if I click on a combo it does not select anything

immagine

Is it possible to force some kind of refresh ?

merco commented 2 years ago

for the RadioButton the problem seems related to "animationProgress" in the paint event. If I force it ==1 the dot appears

merco commented 2 years ago

...same thing for combobox...

valimaties commented 1 year ago

As I see from your form, you have a Datagrid or listview, something there. Could you please post the code from the CurrentCellChanged event (or the event of row changed) from which you populate the other controls?

merco commented 1 year ago

The datagrid contains only search result. The other controls have been populated by form shown

valimaties commented 1 year ago

Could you please post population code here?

merco commented 1 year ago

Yes, sure ! Tell me if you need something else.

Public Class frmAllegati

    Dim _loadingGrid As Boolean = False
    Private _RichiestaAlle As DbEntities.Allegato = Nothing

    Public Sub SetParams(cosa As DbEntities.Allegato)
        _RichiestaAlle = cosa

    End Sub
    Private Function getSelection() As DbEntities.Allegato
        Dim Itm As New DbEntities.Allegato

        If dgw.SelectedRows.Count <= 0 Then Return Itm

        Dim riga As DataGridViewRow = dgw.SelectedRows(0)
        Dim dr As DataRowView = riga.DataBoundItem

        Itm.Codice = dr.Row("Codice").ToString()
        Itm.Rev = dr.Row("Rev").ToString()
        Itm.IdLingua = dr.Row("IdLingua").ToString()
        Itm.FileName = dr.Row("FileName").ToString()
        Itm.WBS = dr.Row("WBS").ToString()
        Return Itm
    End Function
    Private Sub LocalUiMessage(Cosa As String, idx As Long, max As Long)
        If Cosa <> "" Then
            Me.FormEnable(False)
        Else
            Me.FormEnable(True)
        End If
        If max = 0 Then
            Me.lblStatus.Text = Cosa
        Else
            Me.lblStatus.Text = Cosa & " " & idx & " di " & max
        End If

        Me.lblStatus.Refresh()
    End Sub
    Private Sub frmAllegati_Load(sender As Object, e As EventArgs) Handles Me.Load

        Dim ArrRisNew = dbHelper.getRisorseTipo(False)
        Dim ArrRisRic = dbHelper.getRisorseTipo(False)

        Dim rieEmpty As New DbEntities.TipoRisorsa
        rieEmpty.CodRisorsa = ""
        rieEmpty.Descrizione = "<Tutte>"
        ArrRisRic.Insert(0, rieEmpty)

        cboNewRisorsa.DataSource = ArrRisNew
        cboRicRisorsa.DataSource = ArrRisRic

        Dim arr1 = BDB.Languages.ToArray
        Dim L1 As New DbEntities.LinguaList()
        Dim L2 As New DbEntities.LinguaList()
        L2.AddRange(arr1)
        L1.AddRange(arr1)

        Dim Lempty As New DbEntities.Lingua
        Lempty.IdLingua = 0
        Lempty.NomeLingua = "<Universale>"
        L2.Insert(0, Lempty)
        L1.Insert(0, Lempty)

        cboNewLanguage.DataSource = L2

        Lempty = New DbEntities.Lingua
        Lempty.IdLingua = -1
        Lempty.NomeLingua = "<Tutte>"
        L1.Insert(0, Lempty)

        cboRicLingua.DataSource = L1
    End Sub

    Private Sub BtnRicSapBom_Click(sender As Object, e As EventArgs) Handles BtnRicSapBom.Click
        Dim R As Integer = -1
        Dim L As Integer = -1
        Dim W As Integer = -1
        Dim CL As DbEntities.Lingua = cboRicLingua.SelectedItem
        Dim CR As DbEntities.TipoRisorsa = cboRicRisorsa.SelectedItem
        L = CL.IdLingua
        If Not String.IsNullOrEmpty(Me.txtRicRev.Text.Trim) Then
            R = Val(Me.txtRicRev.Text)
        End If
        Dim nome As String = Me.txtRicNome.Text
        If Not String.IsNullOrEmpty(Me.txtRicWbs.Text.Trim) Then
            W = Val(Me.txtRicWbs.Text)
        End If
        If Not String.IsNullOrEmpty(nome) Then nome = "%" & nome & "%"
        Dim dt = dbHelper.GetAllegatiAsDT(Me.txtRicCodice.Text, R, L, nome, W, CR.CodRisorsa)

        _loadingGrid = True
        Me.dgw.AllowUserToAddRows = False
        Me.dgw.AllowUserToDeleteRows = False
        Me.dgw.AllowUserToEditRows = False
        Me.dgw.SelectionMode = DataGridViewSelectionMode.FullRowSelect

        Me.dgw.SetDataTable(dt)
        Me.dgw.ApplicaVisualizzazione()
        _loadingGrid = False
        If Not IsNothing(dt) AndAlso dt.Rows.Count >= 1 Then

            Me.dgw.SelectFirstRow()
            'dgw_SelectionChanged(Nothing, Nothing)
        End If
    End Sub

    Private Sub btnSfoglia_Click(sender As Object, e As EventArgs) Handles btnSfoglia.Click

        If chkCartella.Checked Then
            Dim Ofd As New FolderBrowserDialog
            Ofd.Description = "Importa cartella intera"

            If Ofd.ShowDialog = DialogResult.OK Then
                Me.txtNewFile.Text = Ofd.SelectedPath
            End If
            Ofd.Dispose()
        Else
            Dim Ofd As New OpenFileDialog

            Ofd.Title = "Importa file singolo"
            Ofd.Filter = "Tutti|*.*"

            If Ofd.ShowDialog = DialogResult.OK Then
                Me.txtNewFile.Text = Ofd.FileName
            End If
            Ofd.Dispose()
        End If

    End Sub

    Private Sub btnCreaNew_Click(sender As Object, e As EventArgs) Handles btnCreaNew.Click
        If String.IsNullOrEmpty(Me.txtNewCod.Text.Trim) Then
            UI.ShowExtendedError("Indica il codice!", Me, False)
            Me.txtNewCod.isFocused = True
            Exit Sub
        End If

        Dim art = dbHelper.getArtico(Me.txtNewCod.Text.Trim)
        If art.Codice = "" Then
            UI.ShowExtendedError("Codice non trovato!", Me, False)
            Me.txtNewCod.isFocused = True
            Exit Sub
        End If

        If Val(Me.txtNewRev.Text.Trim) < 0 Then
            UI.ShowExtendedError("Indica la revisione !", Me, False)
            Me.txtNewRev.isFocused = True
            Exit Sub
        End If

        If Me.cboNewLanguage.SelectedIndex < 0 Then
            UI.ShowExtendedError("Indica la lingua !", Me, False)

            Exit Sub
        End If

        If Me.cboNewRisorsa.SelectedIndex < 0 Then
            UI.ShowExtendedError("Indica la tipologia di risorsa !", Me, False)

            Exit Sub
        End If

        If chkFileSingolo.Checked Then
            If String.IsNullOrEmpty(Me.txtNewFile.Text.Trim) Then
                UI.ShowExtendedError("Indica il file!", Me, False)
                Me.txtNewFile.isFocused = True
                Exit Sub
            End If

            If Not System.IO.File.Exists(Me.txtNewFile.Text.Trim) Then
                UI.ShowExtendedError("File non valido " & Me.txtNewFile.Text.Trim, Me, False)
                Me.txtNewFile.isFocused = True
                Exit Sub
            End If
        Else
            If String.IsNullOrEmpty(Me.txtNewFile.Text.Trim) Then
                UI.ShowExtendedError("Indica la cartella !", Me, False)
                Me.txtNewFile.isFocused = True
                Exit Sub
            End If

            If Not System.IO.Directory.Exists(Me.txtNewFile.Text.Trim) Then
                UI.ShowExtendedError("Cartella non valida " & Me.txtNewFile.Text.Trim, Me, False)
                Me.txtNewFile.isFocused = True
                Exit Sub
            End If

            If Not UI.ShowDialog("Aggiungo tutti i file in " & Me.txtNewFile.Text & " ?", "Nuovi allegati", enShowDialogType.Warning, True, Me) Then
                Exit Sub
            End If

        End If

        Dim LastWbs As String = ""
        Dim LastCod As String = ""
        Dim LastRev As String = ""
        Dim Eo As String = ""
        LocalUiMessage("Creazione nuovo allegato...", 0, 0)
        If chkFileSingolo.Checked Then
            Dim Alle As New DbEntities.Allegato
            Dim CL As DbEntities.Lingua = cboNewLanguage.SelectedItem
            Dim CR As DbEntities.TipoRisorsa = cboNewRisorsa.SelectedItem
            Alle.Codice = Me.txtNewCod.Text
            Alle.Rev = Val(Me.txtNewRev.Text)
            Alle.IdLingua = CL.IdLingua
            Alle.WBS = Val(Me.txtNewWBS.Text)
            Alle.CodRisorsa = CR.CodRisorsa
            Me.FormEnable(False)
            Eo = AllegatiManager.ImportNewFile(Alle, txtNewFile.Text)
            Me.FormEnable(True)
            LastWbs = Alle.WBS
            LastCod = Alle.Codice
            LastRev = Alle.Rev
        Else
            Me.FormEnable(False)
            Dim fileList = System.IO.Directory.GetFiles(txtNewFile.Text)
            For Each currentFile As String In fileList
                Dim Alle As New DbEntities.Allegato
                Dim CL As DbEntities.Lingua = cboNewLanguage.SelectedItem
                Dim CR As DbEntities.TipoRisorsa = cboNewRisorsa.SelectedItem
                Alle.Codice = Me.txtNewCod.Text
                Alle.Rev = Val(Me.txtNewRev.Text)
                Alle.IdLingua = CL.IdLingua
                Alle.WBS = Val(Me.txtNewWBS.Text)
                Alle.CodRisorsa = CR.CodRisorsa
                LastWbs = Alle.WBS
                LastCod = Alle.Codice
                LastRev = Alle.Rev
                Dim EoFile As String = AllegatiManager.ImportNewFile(Alle, currentFile)
                If EoFile <> "" Then
                    Eo = Eo & vbCrLf & "Problema con " & System.IO.Path.GetFileName(currentFile) & " " & EoFile
                End If

            Next
            Me.FormEnable(True)
        End If

        LocalUiMessage("", 0, 0)
        If Eo = "" Then
            If Val(LastWbs) <= 0 Then
                Me.txtRicCodice.Text = LastCod
                Me.txtRicRev.Text = LastRev
                Me.txtRicNome.Text = ""
            Else
                Me.txtRicCodice.Text = ""
                Me.txtRicRev.Text = ""
                Me.txtRicNome.Text = ""
                Me.txtRicWbs.Text = LastWbs
            End If

            cboRicLingua.SelectedIndex = 0
            BtnRicSapBom_Click(Nothing, Nothing)
            UI.ShowMessage("OK", "Importa allegato/i", Me)
        Else
            UI.ShowExtendedError(Eo, Me, True)
        End If

    End Sub

    Private Sub BtnViewAlle_Click(sender As Object, e As EventArgs) Handles BtnViewAlle.Click
        Dim itm = getSelection()
        If itm.Codice = "" Then Exit Sub

        AllegatiManager.OpenView(itm)
    End Sub

    Private Sub btnFolder_Click(sender As Object, e As EventArgs) Handles btnFolder.Click
        Dim itm = getSelection()
        If itm.Codice = "" Then Exit Sub

        AllegatiManager.OpenFolder(itm)
    End Sub

    Private Sub btnEliSolo1_Click(sender As Object, e As EventArgs) Handles btnEliSolo1.Click

        Dim itm = getSelection()
        If itm.Codice = "" Then Exit Sub

        If Not UI.ShowDialog("Rimuovo file di " & itm.ToString & " ?", "Rimozione allegato", enShowDialogType.Warning, True, Me) Then
            Exit Sub
        End If
        LocalUiMessage("Rimozione allegato...", 0, 0)
        Me.FormEnable(False)
        Dim Eo As String = AllegatiManager.DeleteFile(itm)
        Me.FormEnable(True)
        LocalUiMessage("", 0, 0)
        If Eo = "" Then
            BtnRicSapBom_Click(Nothing, Nothing)
            UI.ShowMessage("OK", "Rimozione allegato", Me)
        Else
            UI.ShowExtendedError(Eo, Me, True)
        End If
    End Sub

    Private Sub btnEliTutti_Click(sender As Object, e As EventArgs) Handles btnEliTutti.Click

        Dim dt = Me.dgw.MainDataTable

        If dtEOF(dt) Then Exit Sub

        If Not UI.ShowDialog("Rimuovo file di tutta la griglia  ?", "Rimozione allegati", enShowDialogType.Warning, True, Me) Then
            Exit Sub
        End If

        If UI.InputBoxMat("Digita SI per confermare !", "Rimozione allegati", "") <> "SI" Then
            UI.ShowDialog("Operazione annullata! ", "", enShowDialogType.Info, False, Me)
            Exit Sub
        End If

        Dim EoAll As New System.Text.StringBuilder

        LocalUiMessage("Rimozione allegati...", 0, 0)
        Me.FormEnable(False)
        For Each dr As DataRow In dt.Rows
            Dim itm As New DbEntities.Allegato
            itm.Codice = Nz(dr("Codice"), "").ToString
            itm.Rev = Nz(dr("Rev"), "0").ToString
            itm.IdLingua = Nz(dr("IdLingua"), "0").ToString
            itm.FileName = Nz(dr("FileName"), "").ToString
            itm.WBS = Nz(dr("WBS"), "").ToString
            Dim Eo As String = AllegatiManager.DeleteFile(itm)
            If Eo <> "" Then EoAll.AppendLine("Problema con " & itm.ToString & " " & Eo)
        Next
        Me.FormEnable(True)
        LocalUiMessage("", 0, 0)

        If EoAll.Length <= 0 Then
            BtnRicSapBom_Click(Nothing, Nothing)
            UI.ShowMessage("OK", "Rimozione allegati", Me)
        Else
            UI.ShowExtendedError(EoAll.ToString, Me, True)
        End If
    End Sub

    Private Sub dgw_RowDblClick(sender As Object, e As MouseEventArgs) Handles dgw.RowDblClick
        BtnViewAlle_Click(Nothing, Nothing)
    End Sub

    Private Sub btnRinomina_Click(sender As Object, e As EventArgs) Handles btnRinomina.Click
        Dim itm = getSelection()
        If itm.Codice = "" Then Exit Sub

        If Not UI.ShowDialog("Rinomino " & itm.FileName & " ?", "Rinomina allegato", enShowDialogType.Warning, True, Me) Then
            Exit Sub
        End If

        Dim NewName As String = UI.InputBoxMat("Nuovo Nome, completo di estensione", "Rinomina allegato", itm.FileName)
        NewName = NewName.Trim

        If NewName = "" OrElse NewName.ToUpper = itm.FileName.ToUpper Then
            UI.ShowDialog("Operazione annullata! ", "Rinomina allegato", enShowDialogType.Info, False, Me)
            Exit Sub
        End If

        LocalUiMessage("Rinomina allegato...", 0, 0)
        Me.FormEnable(False)
        Dim Eo As String = AllegatiManager.Rinomina(itm, NewName)
        Me.FormEnable(True)
        LocalUiMessage("", 0, 0)
        If Eo = "" Then
            BtnRicSapBom_Click(Nothing, Nothing)
            UI.ShowMessage("OK", "Rinomina allegato", Me)
        Else
            UI.ShowExtendedError(Eo, Me, True)
        End If

    End Sub

    Private Sub dgw_SelectionChanged(sender As Object, e As EventArgs) Handles dgw.SelectionChanged
        Dim itm = getSelection()
        If itm.Codice = "" Then Exit Sub

        Me.txtNewCod.Text = itm.Codice
        Me.txtNewRev.Text = itm.Rev
    End Sub

    Private Sub SelLin(cb As MaterialSkin.Controls.MaterialComboBox, idL As Integer)
        Dim alr As DbEntities.LinguaList = cb.DataSource

        For Each Cl As DbEntities.Lingua In alr
            If Cl.IdLingua = idL Then
                cb.SelectedIndex = alr.IndexOf(Cl)
                Exit For
            End If
        Next
    End Sub
    Private Sub frmAllegati_Shown(sender As Object, e As EventArgs) Handles Me.Shown

        If Not IsNothing(_RichiestaAlle) AndAlso _RichiestaAlle.Codice <> "" Then

            chkFileSingolo.Checked = True

            Me.txtNewCod.Text = _RichiestaAlle.Codice
            Me.txtNewRev.Text = _RichiestaAlle.Rev
            SelLin(cboNewLanguage, _RichiestaAlle.IdLingua)

            If _RichiestaAlle.WBS > 0 Then
                Me.txtNewWBS.Text = _RichiestaAlle.WBS
                Me.txtRicCodice.Text = ""
                Me.txtRicRev.Text = ""
                Me.txtRicWbs.Text = _RichiestaAlle.WBS
            Else
                Me.txtRicCodice.Text = _RichiestaAlle.Codice
                Me.txtRicRev.Text = _RichiestaAlle.Rev
            End If

            BtnRicSapBom_Click(Nothing, Nothing)

            _RichiestaAlle = Nothing
        End If
    End Sub

    Private Sub swMultiSel_CheckedChanged(sender As Object, e As EventArgs)

    End Sub

    Private Sub chkFileSingolo_CheckedChanged(sender As Object, e As EventArgs) Handles chkFileSingolo.CheckedChanged
        chkCartella.Checked = Not chkFileSingolo.Checked
        Me.txtNewFile.Text = ""
        SetHint()
    End Sub

    Private Sub chkCartella_CheckedChanged(sender As Object, e As EventArgs) Handles chkCartella.CheckedChanged
        chkFileSingolo.Checked = Not chkCartella.Checked
        Me.txtNewFile.Text = ""
        SetHint()
    End Sub

    Private Sub SetHint()
        If chkCartella.Checked Then
            txtNewFile.Hint = "Percorso cartella"

        Else
            txtNewFile.Hint = "Percorso file"

        End If
    End Sub

    Private Sub frmAllegati_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
        Me.Dispose()

    End Sub

End Class
valimaties commented 1 year ago

Ok. First of all, I am able to read VB code, even if I'm programming in C#. Please generate the SelectedIndex event for the combobox containing language, and write the code to see in console/debugger which is the index selected. And see how the index changed. I think somewhere in code, your index is set to -1 because no item is selected.

merco commented 1 year ago

mmh... I don't know... for now I blocked the animation in this way (example OnPaint in MaterialRadioButton.cs)

immagine

and with this trick the items appears selected correctly (both selection in comboboxes and dot in radiobuttons)

progmars commented 1 year ago

Confirming something similar with value redraw issues. When opening a dropdown and moving your mouse over the items, sometimes you can notice the dropdown suddenly replacing its value with the hovered one, but when you close it it's normal again. Difficult to reproduce, happens maybe once in 10 tries.

I managed to capture the problem with a simple dropdown. I'm definitely not changing the selected index while the mouse is hovering over. It should not replace the text with MIDINS because I only hovered on the item and did not click on it. As soon as I clicked outside of the dropdown it reverts to the real value. And then you'll see that I opened it up again but then could not reproduce the problem: https://user-images.githubusercontent.com/4199737/184159882-24e658e5-b859-4f9f-a7f5-b7857e73faba.mp4

The trick with animationProgress = 1; in MaterialComboBox did not help in my case.

For now, here's what I did: I added diagnostic output in Paint:

using (NativeTextRenderer NativeText = new NativeTextRenderer(g))
            {
                System.Diagnostics.Trace.WriteLine(Text);

                // Draw user text
                NativeText.DrawTransparentText(
                    Text,

and - surprise! - indeed I managed to capture some cases when Text was being output with the value that matches the item I'm hovering on and not the value that combobox should have at that moment. It's as if something is temporarily modifying Text somewhere and choosing the wrong value.

Added also

            SelectedIndexChanged += (sender, args) =>
            {
                System.Diagnostics.Trace.WriteLine(SelectedIndex);
                Invalidate();
            };

but no changes are detected when the wrong text is being rendered. I tried to dig deeper to find out who/what is modifying SelectedItem / Index / Text properties of the combobox while mouse is only hovering over the items, but could not find anything reasonable.

So I added a workaround:

            SelectedIndexChanged += (sender, args) =>
            {             
                // workaround for a bug changing the text while OnPaint
                _reallySelectedItem = SelectedItem;
                Invalidate();
            };

...
 OnPaint: 
                var text = _reallySelectedItem?.ToString() ?? Text ?? "";