Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
GradientBrush als Ring
Lector
myCSharp.de - Member



Dabei seit:
Beiträge: 862

Themenstarter:

GradientBrush als Ring

beantworten | zitieren | melden

Hallo,

Ich versuche so etwas mit WPF Brushes zu realisieren:

[siehe unten]

Jedoch gibt es nur 2 GradientBrushes im .NET 3.5. Ich habe es weder mit Linear noch mit Radial geschafft. Es handelt sich ja weder um eine Linie noch um einen Kreis.
Es ist eher ein Ring den ich als GradientBrush darstellen möchte.

Ich habe auch schon versucht direkt von GradientBrush abzuleiten bin daran jedoch leider gescheitert.
Laut .NET Reflector wird der eigendliche Zeichenalgorythmus in LinearGradientBrush in einer internal Methode angetriggert auf die ich gar nicht zugreifen kann.

Meine Frage ist nun:
Kann ich solche Farbverläufe mit Standardbrushes darstellen (mal abgesehen von Image/Visual-Brush).
Und falls nein: Wie kann ich selbst ein GradientBrush schreiben. Ich kann zwar von GradientBrush ableiten aber mir fehlt irgendwie der rote Faden wo ich überhaupt anfangen soll und wie ich dort den Farbverlauf zeichne (in welcher Methode, und wann...)
Attachments
private Nachricht | Beiträge des Benutzers
veasel
myCSharp.de - Member



Dabei seit:
Beiträge: 327
Herkunft: M-V

beantworten | zitieren | melden

Hallo,

ich würde nicht in richtung gradient denken sondern das teil einfach über schleifen und das zeichnen von geraden selber zeichnen...

rot = 255.0.0 = 0°
orange 255.255.0 = 60°
gelb = 0.255.0 = 120°
grün = 0.255.255 = 180°
blau = 0.0.255 = 240°
violett = 255.0.255 = 300°

entsprechen R, G oder B hoch und runterzählen lassen und immer wieder zeichnen, oder so ähnlich.
MFG Veasel
private Nachricht | Beiträge des Benutzers
Lector
myCSharp.de - Member



Dabei seit:
Beiträge: 862

Themenstarter:

beantworten | zitieren | melden

d.h. ich müsste SEHR viele Linien malen wenn ich dich richtig verstehe.
Wäre das nicht sehr langsam?
Ausserdem was passiert wenn der Kreis größer wird? Dann würde die Linienmenge irgendwann ausfransen.
private Nachricht | Beiträge des Benutzers
veasel
myCSharp.de - Member



Dabei seit:
Beiträge: 327
Herkunft: M-V

beantworten | zitieren | melden

Guten morgen,

ja, da hast du wohl recht. war auch erstmal nur so eine idee. hab noch nicht mit der erstellung eines gradient beschäftigt.

könnte man nicht nen lineargradient zeichnen auf ein rect vielleicht und dieses recht dann per trasfomation "verbiegen"?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von veasel am .
MFG Veasel
private Nachricht | Beiträge des Benutzers
Lector
myCSharp.de - Member



Dabei seit:
Beiträge: 862

Themenstarter:

beantworten | zitieren | melden

So weit ich weis gibt es 4 TransformationsTypen in WPF:
  1. Verschieben (was hier vollkommen Nutzlos ist)
  2. Rotieren (ja vielleicht hätte ich einen ähnlichen Effekt wenn ich SEHR schnell rotieren würde^^)
  3. Skalieren (größer und kleiner machen nützt hier relativ wenig)
  4. Kippen (bringt auch nichts)


Also ist eine Transformation wohl auch nicht die Lösung...
private Nachricht | Beiträge des Benutzers
veasel
myCSharp.de - Member



Dabei seit:
Beiträge: 327
Herkunft: M-V

beantworten | zitieren | melden

hey...du hast gefragt und ich mach nur ein bißchen brainstorming...

tja, sonst hab ich auch erstmal keine lösung...aber interessant ist es trotzdem.

schreibt aber auch kein anderer was dazu... ist dann wohl doch nicht so trivial.
MFG Veasel
private Nachricht | Beiträge des Benutzers
Lector
myCSharp.de - Member



Dabei seit:
Beiträge: 862

Themenstarter:

beantworten | zitieren | melden

Ich denke ich muss wohl doch ein eigenes Gradient erstellen. Ich poste mal ausschnitte aus LinearGradientBrush laut .NET Reflector:

Dies ist die einzige Methode die das eigendliche Zeichnen antriggert:


[SecurityCritical, SecurityTreatAsSafe]
internal override void UpdateResource(DUCE.Channel channel, bool skipOnChannelCheck)
{
    this.ManualUpdateResource(channel, skipOnChannelCheck);//<-eigendlicher Zeichenvorgang
    base.UpdateResource(channel, skipOnChannelCheck);
}
Wenn das jetzt nicht internal wäre könnte ich UpdateResource ja auch überschreiben und dort ein Gradient malen. Diese Methode ist für mich jedoch leider nicht sichtbar....


Hier das eigendilche Zeichnen:


[SecurityTreatAsSafe, SecurityCritical]
private unsafe void ManualUpdateResource(DUCE.Channel channel, bool skipOnChannelCheck)
{
    if (skipOnChannelCheck || this._duceResource.IsOnChannel(channel))
    {
        DUCE.ResourceHandle handle;
        DUCE.ResourceHandle @null;
        DUCE.MILCMD_LINEARGRADIENTBRUSH milcmd_lineargradientbrush;
        Transform objA = base.Transform;
        Transform relativeTransform = base.RelativeTransform;
        GradientStopCollection gradientStops = base.GradientStops;
        if ((objA == null) || object.ReferenceEquals(objA, Transform.Identity))
        {
            @null = DUCE.ResourceHandle.Null;
        }
        else
        {
            @null = ((DUCE.IResource) objA).GetHandle(channel);
        }
        if ((relativeTransform == null) || object.ReferenceEquals(relativeTransform, Transform.Identity))
        {
            handle = DUCE.ResourceHandle.Null;
        }
        else
        {
            handle = ((DUCE.IResource) relativeTransform).GetHandle(channel);
        }
        DUCE.ResourceHandle animationResourceHandle = base.GetAnimationResourceHandle(Brush.OpacityProperty, channel);
        DUCE.ResourceHandle handle4 = base.GetAnimationResourceHandle(StartPointProperty, channel);
        DUCE.ResourceHandle handle3 = base.GetAnimationResourceHandle(EndPointProperty, channel);
        milcmd_lineargradientbrush.Type = MILCMD.MilCmdLinearGradientBrush;
        milcmd_lineargradientbrush.Handle = this._duceResource.GetHandle(channel);
        double opacity = base.Opacity;
        DUCE.CopyBytes((byte*) &milcmd_lineargradientbrush.Opacity, (byte*) &opacity, 8);
        milcmd_lineargradientbrush.hOpacityAnimations = animationResourceHandle;
        milcmd_lineargradientbrush.hTransform = @null;
        milcmd_lineargradientbrush.hRelativeTransform = handle;
        milcmd_lineargradientbrush.ColorInterpolationMode = base.ColorInterpolationMode;
        milcmd_lineargradientbrush.MappingMode = base.MappingMode;
        milcmd_lineargradientbrush.SpreadMethod = base.SpreadMethod;
        Point startPoint = this.StartPoint;
        DUCE.CopyBytes((byte*) &milcmd_lineargradientbrush.StartPoint, (byte*) &startPoint, 0x10);
        milcmd_lineargradientbrush.hStartPointAnimations = handle4;
        Point endPoint = this.EndPoint;
        DUCE.CopyBytes((byte*) &milcmd_lineargradientbrush.EndPoint, (byte*) &endPoint, 0x10);
        milcmd_lineargradientbrush.hEndPointAnimations = handle3;
        int num2 = (gradientStops == null) ? 0 : gradientStops.Count;
        milcmd_lineargradientbrush.GradientStopsSize = (uint) (sizeof(DUCE.MIL_GRADIENTSTOP) * num2);
        channel.BeginCommand((byte*) &milcmd_lineargradientbrush, sizeof(DUCE.MILCMD_LINEARGRADIENTBRUSH), sizeof(DUCE.MIL_GRADIENTSTOP) * num2);
//Hier werden wohl die Gradientstops durchlaufen
        for (int i = 0; i < num2; i++)
        {
            DUCE.MIL_GRADIENTSTOP mil_gradientstop;
            GradientStop stop = gradientStops.Internal_GetItem(i);
            double offset = stop.Offset;
            DUCE.CopyBytes((byte*) &mil_gradientstop.Position, (byte*) &offset, 8);
            mil_gradientstop.Color = CompositionResourceManager.ColorToMilColorF(stop.Color);
            channel.AppendCommandData((byte*) &mil_gradientstop, sizeof(DUCE.MIL_GRADIENTSTOP));
        }
        channel.EndCommand();
    }
}
private Nachricht | Beiträge des Benutzers
Kaji
myCSharp.de - Member



Dabei seit:
Beiträge: 593
Herkunft: Clausthal-Zellerfeld

beantworten | zitieren | melden

Hallo,

ich denke nicht das du alles selbst machen musst. WPF gibt eigentlich viele möglichkeiten. Vielleicht hilft dir dieser Artikel .

Gruß Daniel
private Nachricht | Beiträge des Benutzers
Lector
myCSharp.de - Member



Dabei seit:
Beiträge: 862

Themenstarter:

beantworten | zitieren | melden

Also wenn es eine Möglichkeit mit Standard-WPF Controls gibt würde ich diese natürlich vorziehen.
Bis jetzt habe ich allerdings immer noch keinen Lösungsansatz gefunden...
private Nachricht | Beiträge des Benutzers
pohlmann
myCSharp.de - Member



Dabei seit:
Beiträge: 67
Herkunft: Willingen

beantworten | zitieren | melden

Vielleicht bringt dir die PathGradientBrush-Klasse eher was.
Religionskriege sind Konflikte zwischen erwachsenen Menschen, bei denen es darum geht, wer den cooleren, imaginaeren Freund hat
private Nachricht | Beiträge des Benutzers
Lector
myCSharp.de - Member



Dabei seit:
Beiträge: 862

Themenstarter:

beantworten | zitieren | melden

Nach dem was ich hier sehe ist das genau das was ich brauche.
Nur kann ich in meiner WPF-Anwendung leider nicht darauf zugreifen weil es eine WinForms-Klasse ist...

Gibt es davon irgendeine WPF-Version?
private Nachricht | Beiträge des Benutzers
Kaji
myCSharp.de - Member



Dabei seit:
Beiträge: 593
Herkunft: Clausthal-Zellerfeld

beantworten | zitieren | melden

Ach so....

Jetzt sehe ich was du willst ^^ ja natürlich gibts das auch so... Man man :P
Hier viel spass damit! :D


Gruß Daniel
private Nachricht | Beiträge des Benutzers
SeeQuark
myCSharp.de - Member

Avatar #avatar-2825.jpg


Dabei seit:
Beiträge: 946

beantworten | zitieren | melden

Ein anderer Ansatz wäre in einem Kegel, den man von oben sieht mit dem LinearGradientBrusch die Oberfläche zeichnen (Kegel gibt es z.Bsp. da).
private Nachricht | Beiträge des Benutzers
Lector
myCSharp.de - Member



Dabei seit:
Beiträge: 862

Themenstarter:

beantworten | zitieren | melden

Zitat von Kaji
Jetzt sehe ich was du willst ^^ ja natürlich gibts das auch so... Man man :P
Hier viel spass damit! :D

Ein netter Artikel aber irgendwie finde ich da auch nur Linear- und RadialGradientBrush.

Hab ich was übersehen???


Kegel wäre auch ein Ansatz aber ist 3D für einen einfachen Farbkreis nicht ein Overkill?
private Nachricht | Beiträge des Benutzers