Das Paint - Event sollte dir weiterhelfen.
Hinterleg in einer Membervariablen die Koordinaten (z. B. bei einem Buttonclick).
Im Paint Event Handler zeichnest du dann das Kreuz an die jeweilige Position.
Um das Paint Event "von Hand" auszulösen, muss die Methode "Refresh()" der PictureBox aufgerufen werden.
myPictureBox.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
namespace foo
{
public partial class myPictureBox : PictureBox
{
Rectangle m_position;
public myPictureBox()
{
InitializeComponent();
m_position = new Rectangle(0, 0, 10, 10);
}
private void myPictureBox_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Brushes.Red);
e.Graphics.DrawEllipse(pen, m_position);
}
private void myPictureBox_MouseClick(object sender, MouseEventArgs e)
{
m_position.X = e.X;
m_position.Y = e.Y;
// force paint event
this.Refresh();
}
}
}
myPictureBox.Designer.cs
namespace foo
{
partial class myPictureBox
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
this.SuspendLayout();
//
// myPictureBox
//
this.Paint += new System.Windows.Forms.PaintEventHandler(this.myPictureBox_Paint);
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.myPictureBox_MouseClick);
((System.ComponentModel.ISupportInitialize)(this)).EndInit();
this.ResumeLayout(false);
}
#endregion
}
}
Es hat sich schon erledigt, da ich den Wert nicht mehr vergleichen muss. Wenn jemand aber Lust hat, kann er mich trotzdem gerne aufklären.
Ich habe ein string-Array, in diesem Array möchte ich, dass im ersten string des Arrays der dritte Buchstabe(also wieder ein Array - char-Array) mit einem anderen Buchstaben verglichen wird.
Beispiel:
public string[] Str = new string[2];
Str[0] = "Grafwald"
string [0][5] == 'w'
so ich habs jetz etwas umgemodelt. es gibt nämlich nen bitmap-konstruktor mit dem ptr auf die pixeldaten. mein einziges problem ist genau dieser IntPtr.
public Bitmap (
int width,
int height,
int stride,
PixelFormat format,
IntPtr scan0
wie bekomm ich ihn dazu das der IntPtr auf mein array zeigt?
Falls es mal jemanden interssiert, hab eine Lösung gefunden. Allerdings nicht mit DataGRidView, sondern mit SourceGrid. http://www.devage.com/Wiki/ViewArticle.aspx?name=sourcegrid&version=0
Meiner Meinung nach keine schlechte Alternative zu DataGrid / DataGRidView.
Die derzeitige Lösung schaut so aus:
internal interface IAbfrageObjekte
{}
public abstract class Basis : IAbfrageObjekte
{}
class Text : Basis
{
internal static Basis Create()
{
return new Text();
}
internal override void Register()
{
Fabrik.reg(FeldTypen.Text, Create);
}
public delegate Basis Creator();
public static class Fabrik
{
public static void fakeinit_Fabrik(){}
static System.Collections.Generic.Dictionary<FeldTypen, Creator> objects;
static Fabrik()
{
objects = new System.Collections.Generic.Dictionary<FeldTypen, Creator>();
Assembly asm = Assembly.GetExecutingAssembly();
foreach (Type typ in asm.GetTypes())
{
if (typ.IsAbstract || typ.GetInterface("IAbfrageObjekte") == null)
continue;
Basis b = (Basis)asm.CreateInstance(typ.FullName);
b.Register();
}
}
public static void reg(FeldTypen typ, Creator c)
{
objects.Add(typ, c);
}
}
Es gefällt mir aber nicht.
a) ich hab keine Erfahrung mit Reflections
b) ich muss mühsig alle Typen untersuchen ob diese zur Fabrik gehören
c) ich muss davon eine Instanz erstellen um die Reg Methode der eigentlichen Klasse aufzurufen.
Der Aufwand gegenüber der alten C++ Lösung ist enorm. Ich hoffe das es eine bessere Möglichkeit gibt, sonst muss ich doch jede einzelne Klasse manuell ansprechen was bei der Anzahl der zu erwartenden Klassen Fehleranfällig wird :o(
Ich kann dir leider nur in C# weiterhelfen, aber im Prinzip müsste es in VB.net ähnlich funktionieren.
Wenn du Arrays marshalen willst, musst du vorher die Größe des Arrays angeben.
In C# geschieht das über ein Attribut:
[MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]
byte[] b;
And dieser Stelle wird jetzt davon ausgegangen, dass ein ByteArray mit der Länge 5 verwendet wird. Wenn du die Größe vorher nicht weist, fällt mir eigentlich nur noch Handarbeit ein (oder unsicheren code zulassen, hab ich aber noch nie probiert und kann deshalb auch nichts dazu sagen).
Du musst die Struktur selbst Byte für Byte durchlaufen und damit ein byteArray füllen. Dieses Byte Array bekommst du dann mit Marshal.Copy(...) unmanaged - und rückwärts genau gleich - Den Pointer Byte für Byte auslesen und damit die Struktur füllen.
@CMatt und AndreasW: Ich sehe gerade das ich die Frage im falschen Forum gestellt habe. Könntet Ihr es zum Framework Forum verschieben?
http://www.c-plusplus.net/forum/viewforum-var-f-is-58.html
Nein, dort ist der übliche Weg, ein Interface zu definieren und anstelle eines Delegate-Objekts eine Instanz des Interfaces weiterzureichen (z.B. für Event-Listener). Wenn man diese Instanz des Interface mit einer Delegate-Instanz vergleicht, hat man dadurch mehr oder weniger das selbe erreicht.
Delegates sind aber ein schöneres Konstrukt IMHO, weil weniger Schreibarbeit erforderlich ist (anonyme Methoden vs. anonyme Klassen) und sie auch nette Sachen wie Futures gleich mitbringen. Man kann ein Delegate asynchron aufrufen und kriegt ein Handle zurück mit dem man irgendwann viel später sich das Ergebnis holen kann.
mi.Insert(0, arrIP[j]);
Das Funktioniert so nicht in C#. In C# sind string Konstant, Du kannst sie also nicht verändert. Statt dessen wird jedesmal ein neuer String erzeugt. Wenn Du das debuggst wirst Du feststellen das in mi nichts interted wird.
Die Zeile müßte daher lauten:
mi = mi.Insert(...)
Wie Du Dir vielleicht denken kannst ist dieser Vorgang natürlich alles anderee als Perfomant, daher hat geeky vollkommen recht, Du musst Hier einen Stringbuilder benutzen.
Schau dir mal SetConsoleCursorPosition() aus dem WindowsSDK an. Sollte zwar n bisschen Interop-Arbeit sein - aber wenn du das machen willst, dürfte s so gehen.
Greetz
M.T.
Enthält dein Buffer immer eine gesamte Zeile oder den gesamten Text / einen Teil?
Wenn letzteres zutrifft könnten die Funktionen String.Contains() oder String.IndexOf() für dich interessant sein
Greetz
M.T.
Ich möchte wissen ob dies möglich ist. Und ein Hinweis welche dll bzw. API ich werwenden sollte.
Ein Codebeispiel wäre natürlich auch toll.
danke
mfg Toms#25
Okay, das SQLFloat auf Real gemappt wird wusst ich nicht, wie dem auch sei.
Double.MaxValue ist größer als SqlDouble.MaxValue, zweiteres ist nämlich nur 1.79E+308 während ersteres 1.79769313486232e308 beträgt was deutlich größer ist.
Deshalb wirst du ein Double.MaxValue nicht rein bekommen.
Was ich für den Einstieg in C/C++ nicht schlecht fand waren die Bücher von Helmut Erlenkötter.
http://www.amazon.de/C-Programmieren-von-Anfang/dp/3499600749/ref=pd_ka_2/302-1752929-0781600?ie=UTF8&s=books&qid=1173085070&sr=8-2
http://www.amazon.de/o/ASIN/3499600773/ref=s9_asin_image_3/302-1752929-0781600
Ja, normal ist das der übliche Weg und ist eigentlich auch ziemlich geil. Ich poste jetzt mal hier nen Link vielleicht hilft's dem Threadersteller ja was.
http://msdn2.microsoft.com/en-us/library/ms173171.aspx