2017-01-10 4 views
0

Ich habe eine Anwendung, die mehrere Steuerelemente auf mehreren Seiten hat. Ich verwende die Telerik Winforms-Steuerelemente. Eine dieser Seiten hat eine RadGridView in einer UserControl, die über eine RadPageViewPage in einer RadPageView ist, die wiederum in einer anderen RadPageViewPage in einer anderen RadPageView verschachtelt ist. Der folgende Code dient im Grunde nur dazu, einen Loading-Spinner zu handhaben, der in seiner eigenen transparenten Form untergebracht ist. Es wird natürlich immer auf einem eigenen Thread aufgerufen.C# Winforms Problem Zentrierung ein Formular über ein Steuerelement, kann es über andere Steuerelemente

private static void RunWaiting(Control c, string text) 
{ 
    wf = new WaitingForm(); 
    wf.drwbieSpinnerFrame.Text = text; 
    wf.ShowInTaskbar = false; 
    wf.Left = c.Left + (c.Width/2); 
    wf.Top = c.Top + (c.Height/2); 
    wf.Width = c.Width; 
    wf.Height = c.Height;    
    wf.FormBorderStyle = FormBorderStyle.None; 
    wf.ControlBox = false; 
    wf.TopMost = true; 
    wf.StartPosition = FormStartPosition.Manual; 

    Application.Run(wf); 
} 

Klar, ich will die Spinner (WaitForm) on-demand über das Zentrum einer Kontrolle erscheinen. Es ist in Ordnung, wenn ich es die Haupt UserControl überbringe, die die RadGridView beherbergt, und ich kann es auch das Elternteil dieser Kontrolle übergeben und auf der RadPageViewPage zentrieren. Wenn ich diese Methode die RadGridView übergebe, wird das Drehfeld überhaupt nicht angezeigt, obwohl der Code aufgerufen wird und die Attribute von "wf" noch festgelegt werden. Kann mir jemand sagen, was ich vermisse?

+0

Ich bin mir nicht sicher, warum Sie ein Formular in einem anderen Thread anzeigen möchten, aber Sie können es [auf diese Weise] (http://stackoverflow.com/a/41263382/3110834) tun. –

+0

Das wird nicht funktionieren. Die Drehfeldform muss in einem separaten Thread sein, da es ausgeführt werden muss, während eine langfristige Operation auf dem Hauptthread ausgeführt wird. Ich rufe diese Methode bereits von einem anderen Thread, aber es sollte über das Steuerelement zentriert werden, das Daten lädt. Dort habe ich Probleme. – CDove

+0

Im Allgemeinen müssen Sie ein Formular in einem anderen Thread nicht öffnen, die zeitaufwendige Aufgabe sollte in einem anderen Thread sein, aber nicht in Ihrem wartenden Formular. Wie auch immer, wenn Sie das Formular von einem anderen Thread öffnen möchten, ist der Link, den ich geteilt habe, die Art, ein Formular von einem anderen Thread zu öffnen, und sicherlich funktioniert es. –

Antwort

0

Leider ist die zeitaufwendige Aufgabe selbst Aktualisierung der Benutzeroberfläche und muss auf dem UI-Thread aus anderen Gründen vorhanden sein, aber ich war in der Lage, eine Lösung mit einer rekursiven Klasse, die mir die passende (x, y) Koordinaten, um ein Formular in der Mitte des Steuerelements anzuzeigen.

private static void RunWaiting(Control c, string text) 
     { 
      wf = new WaitingForm(); 
      wf.drwbieSpinnerFrame.Text = text; 
      wf.ShowInTaskbar = false;   
      int[] tl = GetTopLefts(c); 
      wf.Top = (tl[0] + (c.Height/2)) - (wf.Height/2); 
      wf.Left = (tl[1] + (c.Width/2)) - (wf.Width/2);    
      wf.FormBorderStyle = FormBorderStyle.None; 
      wf.ControlBox = false; 
      wf.TopMost = true; 
      wf.StartPosition = FormStartPosition.Manual; 
      IsHolding = true; 
      Application.Run(wf); 

     } 

Und die Methode ruft es die Positionsdaten zu erhalten:

private static int[] GetTopLefts(Control c) 
     { 
      int top, left; 
      top = c.Top; 
      left = c.Left; 
      if (c.Parent != null) 
      { 
       int[] parentPoint = GetTopLefts(c.Parent); 
       top += parentPoint[0]; 
       left += parentPoint[1]; 
      } 
      return new int[] { top, left }; 
     } 

Sie wahrscheinlich durch diese ganz gut bekommen konnte durch die endgültige Ausgabe von GetTopLefts() macht ein Point, aber etwas über diese Art und Weise fühlte willkürlich zuverlässiger.

+1

Alles, was Sie brauchen, ist 'c.Parent.PointToScreen (c.Location);'. Warum verwenden Sie eine rekursive Methode ?! –

+0

Anstelle von 'int []' können Sie 'Point' verwenden. –

+0

'c.Parent.PointToScreen (c.Location)' verursachte einige Probleme in der Terminal-Server-Umgebung. Ich weiß nicht, warum es so war, aber Sie können nicht mit der rohen Mathematik in einer rekursiven Methode argumentieren, und das funktioniert wunderbar. – CDove

Verwandte Themen