Laden...

Form mit runden Ecken?

Erstellt von Spiker vor 18 Jahren Letzter Beitrag vor 16 Jahren 18.198 Views
S
Spiker Themenstarter:in
18 Beiträge seit 2005
vor 18 Jahren
Form mit runden Ecken?

Hallo Ihr da draussen,

ich habe schon ein bischen gebastelt mit Path und regions..
das ist ja alles ganz nett. was mir bisher nicht gelungen ist, ist eien funktion, mit der ich einfach bei einer biliebigen Form die ecken sozusagen abrunden kann.

Immer mehr Applikationen haben heutzutage diese abgerundeten Ecken.

habt ihr da Tips?

1000 Dank.

Gruß Spiker

N
4.644 Beiträge seit 2004
vor 18 Jahren
S
Spiker Themenstarter:in
18 Beiträge seit 2005
vor 18 Jahren
Nicht runde Form.. nur die ecken etwas rund....

das geht leider so nicht!

N
4.644 Beiträge seit 2004
vor 18 Jahren

Das funktioniert.

Gehts vielleicht etwas genauer? Oder sollen wir raten?

S
Spiker Themenstarter:in
18 Beiträge seit 2005
vor 18 Jahren
es geht genauer :)

also wenn die form eine breite von 700 und eine höhe von 100 hat, dann sieht das nicht mehr vernünftig aus.

N
4.644 Beiträge seit 2004
vor 18 Jahren

Dann wirst Du es wohl selbst anpassen müssen. Oder suchst Du vielleicht nur die XP-Styles um abgerundete Ecken zu erhalten.

2.921 Beiträge seit 2005
vor 18 Jahren

Hi spiker,


#region myCSHARP Library

// -----------------------------------------------------------------------------
// The contents of this file are subject to the GNU Lesser General Public Licens
// (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
// [URL]http://www.gnu.org/copyleft/lesser.html[/URL]
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
// the specific language governing rights and limitations under the License.
//
// Copyright 2005 - myCSHARP Team - All Rights Reserved.
// Authors:
// - Name of Author <Email@email.de>
//
// Contributors: none
//
// Known Issues:
// - None
//
// You may retrieve the latest version of this file at the myCSHARP
// home page, located at [URL]http://mycsharp.sourceforge.net[/URL]
//
//------------------------------------------------------------------------------------
// Version: 0.0
// Description: A short description of what the file do
//------------------------------------------------------------------------------------

#endregion
using System;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace SkinLib
{
	/// <summary>
	/// 
	/// </summary>
	public class RoundedRectangleRegion //EDIT: Regionshape hier gelöscht, da nicht benötigt.
	{
		public RoundedRectangleRegion()
		{
			// 
			// TODO: Add constructor logic here
			//
		}

		public Region GetRoundedRect(RectangleF BaseRect, int Radius )
		{
			// If corner radius is less than or equal to zero, return the original rectangle
			if (Radius <= 0) { return new Region(BaseRect); }
			// If corner radius is greater than or equal to half the width or height (whichever is shorter) then 
			//return a capsule instead of a lozenge.
			if (Radius >= (Math.Min(BaseRect.Width, BaseRect.Height) / 2.0))
				return GetCapsule(BaseRect);

				float Diameter = Radius + Radius;
				RectangleF ArcRect = new RectangleF(BaseRect.Location, new SizeF(Diameter,Diameter));
				GraphicsPath RR = new GraphicsPath();
				// top left arc
				RR.AddArc(ArcRect, 180, 90);
				// top right arc
				ArcRect.X = BaseRect.Right - Diameter;
				RR.AddArc(ArcRect, 270, 90);
				// bottom right arc
				ArcRect.Y = BaseRect.Bottom - Diameter;
				RR.AddArc(ArcRect, 0, 90);
				// bottom left arc
				ArcRect.X = BaseRect.Left;
				RR.AddArc(ArcRect, 90, 90);
				RR.CloseFigure();

			return new Region(RR);
		}

		public Region GetCapsule(RectangleF BaseRect)
		{
			float Diameter;
			RectangleF ArcRect;
			GraphicsPath RR = new GraphicsPath();

			try
			{
				if (BaseRect.Width>BaseRect.Height)
				{
					//return Horizonal capsule
					Diameter = BaseRect.Height;
					ArcRect = new RectangleF(BaseRect.Location, new SizeF(Diameter, Diameter));
					RR.AddArc(ArcRect, 90, 180);
					ArcRect.X = BaseRect.Right - Diameter;
					RR.AddArc(ArcRect, 270, 180);

				}
				else if (BaseRect.Height > BaseRect.Width)
				{
					// Return vertical capsule
					Diameter = BaseRect.Width;
					ArcRect = new RectangleF(BaseRect.Location, new SizeF(Diameter, Diameter));
					RR.AddArc(ArcRect, 180, 180);
					ArcRect.Y = BaseRect.Bottom - Diameter;
					RR.AddArc(ArcRect, 0, 180);
				}
				else
				{
					//return circle
					RR.AddEllipse(BaseRect);
				}
			}
			catch(Exception e)
			{
				string sLastError = e.Message;
				RR.AddEllipse(BaseRect);
			}
			finally
			{
				RR.CloseFigure();
			}
			return new Region(RR);
		}
	}
}

Hier ein Codeauszug, den ich auch für meine Skins verwende,

du wendest einfach die Rounded-Rectangleregion auf Dein Form an, und dann sollte die Form das gewünschte Aussehen haben.


Verwende Sie zum Beispiel so:

		public bool InitRegions()
		{
			RoundedRectangleRegion rndRectRegion = new RoundedRectangleRegion();
			if (this.Form != null)
			{
				foreach(Control ctrl in m_frmForm.Controls)
				{
					ctrl.Region = rndRectRegion.GetRoundedRect(new RectangleF (ctrl.ClientRectangle.Left, ctrl.ClientRectangle.Top, ctrl.ClientRectangle.Width, ctrl.ClientRectangle.Height),5);
					#if DEBUG
						//ctrl.Text = "Blub";
					#endif
				}
				return true;
			}
			return false;
		}

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

S
Spiker Themenstarter:in
18 Beiträge seit 2005
vor 18 Jahren
:RegionShape unbekannt

Hi, vielen dank für den Code,

public class RoundedRectangleRegion:RegionShape

hier wird gemeckert, weil RegionShap unbekannt ist. habe in der .net libary auch nix gefunden.
Was hat es damit aufsich, ist es einen eigene klasse von Dir?

Gruß Spiker

S
Spiker Themenstarter:in
18 Beiträge seit 2005
vor 18 Jahren
:)

Noch mal fettes DANKE! läuft nun alles, (habe einfach die Vererbeung weggelassen.

2.921 Beiträge seit 2005
vor 18 Jahren

Genau, das ist eine Klasse von mir, die ich genommen habe, um Forms auch noch andere Regions verpassen zu können. Aber das hast du ja schon selbst rausgefunden.

Zur Erklärung:
Der Trick ist hier einfach, das Rechteck aus 8 Teilen zusammenzusetzen.
Jeweils eine Linie(1. Teil) mit einem abgerundeten Bogen (2. Teil) und das eben um vier Ecken. 😉

Der Code ist aus meiner Skinklasse (RegionShape)

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

K
95 Beiträge seit 2005
vor 18 Jahren

hallo, hab den hier verwendeten code genommen, aber bei mir passiert nichts ...
ich habe meinem projekt die classe RoundRectangleRegion hinzugefügt.
dann habe ich in meiner gewünschten form, ein diesem fall in Form1, den obigen aufruf hinzugefügt und zwar angepasst auf meine form:


public bool InitRegions()
        {
            Form1 haupt = new Form1();
            RoundedRectangleRegion rndRectRegion = new RoundedRectangleRegion();
            if (haupt != null)
            {
                foreach (Control ctrl in haupt.Controls)
                {
                    ctrl.Region = rndRectRegion.GetRoundedRect(new RectangleF(ctrl.ClientRectangle.Left, ctrl.ClientRectangle.Top, ctrl.ClientRectangle.Width, ctrl.ClientRectangle.Height), 5);
#if DEBUG
                    //ctrl.Text = "Blub";
#endif
                }
                return true;
            }
            return false;
        }

der compiler läuft auch durch, aber ich habe keine runde ecken, warum? was mache ich falsch?
Viele Grüße und danke für die Hilfe,
Stephan

2.921 Beiträge seit 2005
vor 18 Jahren

Poste mal das Projekt. Denn Für TabControls oder Controls in Panels usw. mußt Du noch einen Schritt machen, falls das so sein sollte...

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

P
38 Beiträge seit 2005
vor 18 Jahren

Hallo dr4g0n76,
bin zwar etwas spät dran ... 🙂

Wo muss man den den Code einbinden, dass gleich das erste Form die Rundungen erhält? Bin in C# noch nicht so geübt 🙁

Grüßle

Mike

2.921 Beiträge seit 2005
vor 18 Jahren

In deiner Form mußt du

this.Region = daswasdieentsprechendeFunktionDerKlassezurückliefert setzen.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

432 Beiträge seit 2005
vor 16 Jahren

hi dragon,
hi alle runde ecken (und skin-) fans,

ich habe aus aktuellem anlass ein bisschen mit dragons code herumgebastelt und folgende änderungen/erweiterungen vorgenommen:*Die Methode heisst ein bissi anders 😉

*Sie erhält das Control Objekt, dessen Region zu ändern ist, komplett, statt nur seine Dimension *Die Radien von oberen und unteren Ecken können separat angegeben werden

Folgendes ist mir aufgefallen:
Wenn diese Methode auf ein Control (UserControl, Form, etc.) angewendet werden soll, ist es dringend erforderlich, das nach dem Zeichnen zu tun.

Ist das Control bspw. mit Dock.Top in einem Panel, dann darf die Methode erst nach dem myPanel.Controls.Add(rundeEckenDings) abgearbeitet werden.

Da mein UserControl selbst die Sache mit dem Skin in die Hand nehmen soll, habe ich einfach die Anwendung des Skins in das Paint-Ereignis gepackt

protected override void OnPaint(PaintEventArgs e)
{
   base.OnPaint(e);
   if (_SkinType != eSkinType.None)
   {
      Skin skin = new Skin(this, _SkinType);
   }
}


...und der Konstruktor des Skins übernimmt die Arbeit schon bei der Initialisierung mit dem Control, auf dem es zur Anwendung kommen soll:


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace CCL.Common
{
   [Flags]
   public enum eSkinType
   {
      None           = 0, 
      RoundedEdges   = 1, 
      Shadowed       = 2
   }

   public class Skin
   {
   #region .ctor
     public Skin(Control control, eSkinType skin)
     {
        if ((skin & eSkinType.RoundedEdges) == eSkinType.RoundedEdges)
           control.Region = RoundRegionOf(control, 9, 5);
     }
   #endregion

   #region Methods
      public Region RoundRegionOf(Control control, int upperRadius, int lowerRadius)
      {
      // If corner radius is less than or equal to zero, return the original rectangle
         if ((lowerRadius <= 0) || (upperRadius <= 0)) 
            return new Region(control.ClientRectangle); 

      // If corner radius is greater than or equal to half the width or height (whichever is shorter) then return a capsule instead of a lozenge
         double limitVal = (Math.Min(control.ClientRectangle.Width, control.ClientRectangle.Height) / 2.0);
         if ((lowerRadius >= limitVal) || (upperRadius >= limitVal))
            return GetCapsule(control.ClientRectangle);

         GraphicsPath gp = new GraphicsPath();
         Rectangle rect = new Rectangle(control.ClientRectangle.Location, new Size((2 * upperRadius), (2 * upperRadius)));

      // top left arc
         gp.AddArc(rect, 180, 90);

      // top right arc
         rect.X = control.ClientRectangle.Right - (2 * upperRadius);
         gp.AddArc(rect, 270, 90);

      // bottom right arc
         rect = new Rectangle(rect.X + (2 * (upperRadius - lowerRadius)), rect.Y, (2 * lowerRadius), (2 * lowerRadius));
         rect.Y = control.ClientRectangle.Bottom - (2 * lowerRadius);
         gp.AddArc(rect, 0, 90);

      // bottom left arc
         rect.X = control.ClientRectangle.Left;
         gp.AddArc(rect, 90, 90);

         gp.CloseFigure();

         return new Region(gp);
     }
   #endregion
   }
}


gruß
ron