Hi designerfreak,
zu 3.) Autostart von Windows
zu 4.)
mit
protected override void WndProc(ref Message m)
{
const int WM_NCHITTEST = 0x84;
const int HTCAPTION = 0x02;
const int HTCLIENT = 0x01;
base.WndProc(ref m);
if (m.Msg == WM_NCHITTEST && (int)m.Result == HTCAPTION)
{
m.Result = (IntPtr)HTCLIENT;
}
}
wird die form fixiert.
Grüße,
psy
Hi kpatrickk,
du musst das Attribute DesignerSerializationVisibility auf
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
setzen.
Grüße,
psy
Hi Thomas Wüst,
die Hintergrundgrafik nicht über OnPaint und DrawImage zeichnen, sondern
einfach als BackgroundImage der Form setzen.
Grüße,
psy
Hi JunkyXL,
ich glaube er wollte auch Änderungen zum Momentan- und nicht Standardwert haben.
Zudem gibt es Properties die kein DefaultValue haben können (zumindest nicht über das Attribute).
Und da ist die Variante, die ich beschrieben habe, zwar kompliziert, aber wesentlich flexibler.
Grüße,
psy
Hi antoschka,
Erstmal ein Attribute anlegen:
[AttributeUsage(AttributeTargets.Property)]
public class ValueChangedAttribute : Attribute
{
private bool itsIsChanged = false;
public bool IsChanged
{
get
{
return itsIsChanged;
}
set
{
itsIsChanged = value;
}
}
public ValueChangedAttribute()
{
}
}
Dann eine kleine Testklasse zur Demonstration
public class TestClass
{
private int itsTestValue = 0;
[ValueChangedAttribute()]
public int TestValue
{
get
{
return itsTestValue;
}
set
{
itsTestValue = value;
}
}
public TestClass()
{
}
}
Und eine kleine Test-Anwendung
// Anmelden
private void button1_Click(object sender, System.EventArgs e)
{
propertyGrid1.SelectedObject = itsTestClass;
propertyGrid1.PropertyValueChanged += new PropertyValueChangedEventHandler(propertyGrid1_PropertyValueChanged);
}
// Value Changed setzen
private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
object aAttribute = e.ChangedItem.PropertyDescriptor.Attributes[typeof(ValueChangedAttribute)];
if (aAttribute != null)
{
((ValueChangedAttribute)aAttribute).IsChanged = true;
}
}
// Abfrage
private void button2_Click(object sender, System.EventArgs e)
{
string aText = "";
PropertyDescriptorCollection aCol = TypeDescriptor.GetProperties(itsTestClass);
foreach (PropertyDescriptor aProp in aCol)
{
object aAttribute = aProp.Attributes[typeof(ValueChangedAttribute)];
if (aAttribute != null)
{
aText += aProp.Name + ", changed: " + ((ValueChangedAttribute)aAttribute).IsChanged.ToString() + "\r\n";
}
}
MessageBox.Show(aText);
}
Zuerst mal das Objekt (eine TestClass) dem Grid übergeben, dabei (EINMAL) an den Event (PropertyValueChanged) anmelden.
Dann erscheint die Klasse im Grid.
Solltest du jetzt den Status abfragen, ist dieser "false" (also nix geändert).
Änderst du jetzt das TestValue im Grid (zb von 0 auf 1) und fragst wieder ab,
bekommst du die Information dass der Status "true" ist, das Property wurde also geändert.
Grüße,
psy
Hi Herzog,
der Code im Beispiel ist beim besten Willen nicht zu kompliziert.
Wenn du damit Probleme hast, siehts eh schlecht mit C#-Programmierung aus 😁
Aber der Ablauf ist ganz einfach:
Fertsch 🙂
Grüße,
psy
Hi Schnueggel,
Matrixtransformierung ist genau das Stichwort.
Folgender Code zeigt wie einfach es geht
Image aImage = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics aGraphics = Graphics.FromImage(aImage);
aGraphics.Clear(Color.White);
Rectangle aRect = new Rectangle(0, 0, 50, 50);
LinearGradientBrush aBrush = new LinearGradientBrush(aRect, Color.Black, Color.Blue, 0.0f);
aBrush.TranslateTransform(20, 20);
aGraphics.FillRectangle(aBrush, new Rectangle(20, 20, 50, 50));
aBrush.TranslateTransform(80, 0);
aGraphics.FillRectangle(aBrush, new Rectangle(100, 20, 50, 50));
pictureBox1.Image = aImage;
aGraphics.Dispose();
Wenn du also zb nur den Start und Endpunkt ändern willst, reicht ne Translation.
Grüße,
psy
PS: Thema bitte nach Grafik und Sound verschieben.
Hi Term!nX,
zu 3.) Wie Programmierhans schon sagte, muss Refresh vom GUI-Thread kommen.
Also entweder BeginInvoke oder Windows.Forms.Timer
RefreshProperties wird dein Problem nicht lösen, da dieses Attribute nur ein Repaint auslößt wenn sich ein Property im GRID ändert (und nicht in der Klasse selbst).
Grüße,
psy
Hallo,
es geht noch speicherschonender, wenn du bei den Pens nur Farbe und Breite änderst und bei den Brushs nur die Farbe änderst. Dabei musst du aber deine Zeichenreihenfolge beachten.
Denn genau diese Properties kann du ändern, ohne das GDI-Objekt neu instanziieren zu müssen (im Gegensatz zum Font.Size, etc).
Du kannst also nur einen globalen Pen und einen globalen Brush anlegen und deine Get-Funktionen entsprechend anpassen.
/// <summary>
/// Übergibt ein Pen-Objekt
/// </summary>
/// <param name="color">Farbe des Pens</param>
/// <returns>der Pen</returns>
public Pen GetPen(Color color)
{
itsGlobalPen.Color = color;
return itsGlobalPen;
}
/// <summary>
/// Übergibt ein Pen-Objekt
/// </summary>
/// <param name="color">Farbe des Pens</param>
/// <param name="size">Größe des Pens</param>
/// <returns>der Pen</returns>
public Pen GetPen(Color color, float size)
{
itsGlobalPen.Color = color;
itsGlobalPen.Width = size;
return itsGlobalPen;
}
Der Nachteil:
Pen aRedPen = GetPen(Color.Red)
Pen aGreenPen = GetPen(Color.Green)
und dann zeichnen mit beiden Stiften geht NICHT. (beide wären grün)
Du musst deine Reihefolge beachten und immer den Pen neu holen, falls du mit einer anderen Farbe zeichnen willst.
Grüße,
psy
Hi bear99,
Wenn ich ein Dialogfenster (Einstellungen, Info, ...) über der Main Form Bewege dann sieht man deutlich das Neuzeichnen, darum ging es mir
probiere doch einfach mal mein Beispiel aus ... es wird nix neugezeichnet, auch wenn ein Dialog drüber geschoben wird. Warum das so ist, habe ich ja schon erwähnt ...
Grüße,
psy