Ich nutze zum Auffinden vom Memory-Leaks das hier:
Gerade das Auffinden von Referenzen, die ein finalisieren der Objekte verhindern (wie von Palin beschrieben) IMHO sehr gut geeignet...
Solltest Du doch mit zwei Tabellen weiterarbeiten wollen und die 'nervigen' joins vermeiden wollen, solltest Du Dir vllt. ein View anlegen, in dem Du die beiden Tabellen zusammenfasst.
Um einer WinForms-Anwendung einen eigenen Look zu geben, gibt es diverse kommerzielle und freie Frameworks. Hier ein paar Anregungen:
frei verfügbar:
http://thielj.github.io/MetroFramework/
https://github.com/IgnaceMaes/MaterialSkin
kommerziell
http://www.devexpress.com
http://www.devcomponents.com
http://www.telerik.com
Stell dir mal folgendes vor: Du hast ein Buch mit 400 Seiten. Auf Seite 351 ist plötzlich eine ganz andere Farbe und Schriftart. Seite 352 entspricht dann wieder allen anderen Seiten. Ist nicht schön oder?
Das ist ein IMHO ziemlich dämlicher Vergleich: Sieht denn jedes Buch in Deinem Regal gleich aus? Eine moderne UI kann heute den Erfolg/Misserfolg einer Anwendung entscheidend beeinflussen und den Unterschied zwischen 'mir' und 'meiner Konkurrenz' ausmachen. Ideal sind abei natürlich Lösungen, die es dem User überlassen, was er bevorzugt...
Vielen Dank für die 'Anteilnahme'.
Für das Schreiben der Daten war/ist eine ältere, in VB6 geschriebene Anwendung verantwortlich. Ich greife auf die Datenbank nur lesend zu (Quelltext steht mir leider nicht zur Verfügung).
Zum Testen meiner Anwendung habe ich die Datenbank aus einem bestehenden MS SQL Server 2012 (mit dem auch die Anwendung arbeitet und die Daten schreiben UND lesen kann). Dort habe ich die Datenbank mittels detach 'abgehängt', dann auf meinen Rechner (MS SQL 2014) kopiert und mit attach eingebunden. Versuche ich nun die Daten auf meinem Rechner zu lesen erhalte ich immer ein byte[] in dem die Daten UTF8 codiert vorliegen (16bit pro 'Byte' - immer das 'richtige' Byte gefolgt von einem Byte mit dem Wert 0x00). Mittels Encoding kann ich diese Daten problemlos verarbeiten und die ursprüngliche Datei wiederherstellen).
Verwende ich nun mein Programm gegen den ursprünglichen SQL Server 2012, erhalte ich das beschriebene Verhalten - also immer 'O_L_E_-O_b_j_e_k_t' wobei der Unterstrich für 0x00 steht. Schaue ich mir die Tabelle mit dem SQL Manager an, kann ich die korrekten Daten lesen.
Meine Vermutung ging nun in die Richtung, dass ich auf dem MS SQL Server noch irgendwas einstellen muss/kann, dass er die tatsächlichen 'Binärdaten' liefert - allerdings finde ich nichts dazu.
@BerndFfm
Den Artikel in Deinem Link kannt ich shcon - auch mit dem Code dort scheitert es immer wieder an der Zeile:
byte[] bData = (byte[])cmdQuery.ExecuteScalar();
die bereits die falschen 'Rohdaten' liefert.
Ich werde morgen nochmal versuchen mit einer anderen Framework-Version als der derzeit genutzten 4.5 zu arbeiten - vllt. ist es ja auch ein 'Bug' im .NET-Framework.
verwendetes Datenbanksystem: MS SQL (2012 und 2014)
Hallo,
ich stehe vor einem Problem, bei dem ich mir nicht mehr zu helfen weiß, auch Google etc. konnte mir leider nicht helfen.
Ich habe eine Tabelle Notizen, in der es eine Spalte des Typs 'Image' (die Datenbank ist schon älter, deshalb wurde hier noch mit 'Image' gearbeitet) mit dem Namen 'Datenfeld' gibt. In diesem Datenfeld sind Blobs/Streams/Binärdaten beliebiger Dateien gespeichert (PDF, DOC etc.). Dieses Datenfeld möchte ich auslesen um den Inhalt wieder als Datei speichern zu können. Der Inhalt von Datenfeld ist ein UTF8 codierter Stream. Soweit so gut.
Ich habe nun folgende Varianten ausprobiert, die auf einem MS SQL Server 2014 auch alle problemlos funktionieren:
Variante 1:
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("select Notiznr, Datenfeld from Notizen where Notiznr = 1000", connection))
{
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
int fieldpos = reader.GetOrdinal("Datenfeld");
if (reader.IsDBNull(fieldpos))
break;
byte[] daten = new byte[]{};
using (MemoryStream mem = new MemoryStream())
{
using (Stream output = reader.GetStream(fieldpos))
{
output.CopyTo(mem);
daten = mem.ToArray();
}
}
}
}
}
connection.Close();
}
Variante 2:
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("select Notiz, Datenfeld from Notizen where Notiznr = 1000", connection))
{
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
int fieldpos = reader.GetOrdinal("Datenfeld");
if (reader.IsDBNull(fieldpos))
break;
long totalbytes = reader.GetBytes(fieldpos, 0, null, 0, 0);
if (totalbytes < 1)
break;
long bytesgelesen = 0;
byte[] daten = new byte[totalbytes];
long startpos = 0;
while (bytesgelesen < totalbytes)
{
bytesgelesen += reader.GetBytes(fieldpos, startpos, daten, (int)startpos, 1024); // tried with several block sizes...
startpos += 1024;
}
}
}
}
connection.Close();
}
Variante 3:
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("select Datenfeld from Notizen where Notiznr = 1000", connection))
{
byte[] daten = (byte[])command.ExecuteScalar();
}
connection.Close();
}
und Variante 4:
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("select Notiznr, Datenfeld from Notizen where Notiznr = 1000", connection))
{
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
int fieldpos = reader.GetOrdinal("Datenfeld");
if (reader.IsDBNull(fieldpos))
break;
byte[] daten = (byte[])reader[fieldpos];
}
}
}
connection.Close();
}
Nun habe ich die exakt gleiche Datenbank mit zwei verschiedenen MS SQL Server 2012 Installationen ausprobiert und erhalte dort statt der erwünschten Daten immer 20 Bytes, die den Text 'OLE-Objekt' repräsentieren (UTF8, deswegen 20 Bytes). Ich habe auch schon versucht statt der Sql-Klassen mit OleDB zu arbeiten (funktioniert auf dem MS SQL Server 2014 wieder problemlos) aber bekomme immer das gleiche Ergebnis.
Weiß jemand Rat?
Gruß,
wcseller
Schau Dir mal den Quellcode von MaterialSingleLineTextField an. Dort wird ähnlich wie in den von Dir im erstn Post angegeben Varianten eine Textbox in ein Control eingebettet. Dort könntest Du ansetzen um Dir ein eigenes Control abzuleiten und die entsprechenden Zeichenroutine zu überschreiben (OnPaint).
Verwende zwar das DataGridView nicht mehr selbst, aber vllt. hilft Dir das:
Schau Dir mal die Methode CommitEdit des DataGridViews an. Ggf. in Kombination mit den Eigenschaften IsCurrentCellDirty und IsCurrentRowDirty.
Mit den Stichworten 'datagridview force commit new row' findest Du weitere Ansätze/Hinweise...
Alle drei von Dir hier angegeben Varianten funktionieren. Was also genau bekommst Du nicht hin?
Lustiger Post: So nach dem Motto - mach mal meine Arbeit...
Einen 'einfachen' Tipp dazu wirst Du nicht finden. Du benötigts ein Calender-Control und musst via Outlook-API oder Exchange-API auf die Informationen der Kalender zugreifen.
Und nun viel Spass beim 'google'n...
Versuche das ganze von einer bestimmten Datenbank unabhängig zu machen. ORM ist hier Dein Stichwort (nHibernate, DevExpress XPO u.ä.).
Als Datenbank möchte ich noch FireBird SQL Server (www.firebirdsql.org) in den 'Ring' werfen - kostenlos, leistungsfähig und extrem einfach zu händeln (nahzu NULL Verwaltungsaufwand, einfach zu sichernde Datenbanken, leicht zu installieren usw.) - insbesondere wenn Du über ein 'offline'-Variante nachdenkst (Stichwort 'embedded' Datenbank).
Dein Problem ist eher
das dynamisch eine Oberfläche mit ziemlich vielen Controls aufbaut.
Das ist nie eine Gute Wahl, denn in WindowsForms hat jedes Control mindestens ein Handle und die werden schnell knapp, bzw werden alle per WindowsMessage nacheinander gemalt.
Besser ist es wenn man partout viele Controls benutzen will auf WPF umzusteigen oder das meiste selber zu zeichnen.
Das Limit liegt bei ungefähr 10.000 Handles pro Prozess - wenn die ausgeschöpft werden, hat man ein Design-Problem, dass auch mit WPF nicht zu erschlagen ist.
Das Problem wird eher sein, dass das Eltern-Control bereits sichtbar ist während die 'Kind'-Controls hinzugefügt werden. Hier bietet es sich an das Eltern-Control zu verbergen, dann die KindControls hinzuzufügen und anschließend das Eltern-Control wieder anzuzeigen. Um 'flackern' zu vermeiden sollte ausserdem DoubleBuffered beim Eltern-Control auf true gestellt und die Kind-Controls bereits in der korrekten Größe hinzugefügt werden (so man mit Docking und ähnlichem arbeitet).
Ausserdem sollte man 'Transparent' als Background-Color generell aber besonders für Panels und ähnliche Container vermeiden.
Wie inflames2k schon richtig festgestellt hat, liegt das an der sog. Z-Order der Panels (Reihenfolge). Diese kannst Du aber auch nach dem Hinzufügen im Designer jederzeit ändern. Dazu klickst Du einfach auf das Control (z.B. dein Panel) und dann die Schaltfläche 'In den Vordergrund' oder 'In den Hintergrund'. Das Panel jedesmal zu entfernen und wieder einzufügen ist also nicht notwendig...
Natürlich funktioniert die von Tossi65 vorgeschlagene Variante mit dem TableLayout in Deinbem Fall ebenfalls.
Also ich hab grad mal nach 'writing hardware driver' gesucht und aus Anhieb das hier gefunden:
https://msdn.microsoft.com/en-us/library/windows/hardware/ff554811(v=vs.85).aspx
https://www.osronline.com/article.cfm?article=20
da gibt es aber noch einiges mehr...
Willst Du tatsächlich einen 'Treiber' schreiben, damit andere Anwendungen Dein Gamepad nutzen können (also einen 'echten' Treiber) oder soll nur das 'Gamepad' in Deiner eigenen Anwendung funktionieren?
Im ersten Fall: Vergiss C# - das wird nix. Echte Treiber kann man nicht in C# schreiben (typischerweise heutztage mit C oder Assembler) - ausserdem ein sehr komplexes Thema...
Wenn das zweite der Fall sein sollte, verstehe ich den ganzen Aufriss nicht - kapsele die Abfrage der seriellen Schnittstelle in einer eigenen Klasse und wirf Events wenn der Klick auftritt.
Wie wäre es mit einer verbesserten Version des WebBrowser-Controls (basierend auf dem IE):
z.B.: The most complete C# Webbrowser wrapper control
Alternativ kannst Du natürlich auch eine der üblichen verdächtigen benutzen:
https://www.chromium.org/
https://www.webkit.org/
usw.
Ein paar mehr Informationen zum Thema findest Du z.B. hier: C#: WebBrowser vs Gecko vs Awesomium vs OpenWebKitSharp: What To Choose And How to Use
Der gezeigte Code gibt sehr wohl Sinn und ist bei Zugriffen auf die GUI aus anderen Threads heraus sogar erforderlich!
Ich bezog mich mit meiner Aussage nicht auf die Verwendung von InvokeRequired und Invoke an sich, sondern vielmehr auf die Verwendung in einer überschriebenen Methode OnResize des Forms.
ICH zumindest kann mir nicht vorstellen, wozu ein Aufruf dieser Methode von ausserhalb des GUI-Threads sinnvoll sein sollte.
Ich kann mir kein Szenario vorstellen, bei dem dieser Code überhaupt einen Sinn ergibt. Hat die Anwendung mehrere GUI-Threads? Da scheint mir ganz grundlegend was falsch zu laufen...
Die PictureBox selbst lässt sich nicht beleibig drehen, der Inhalt (Image) aber sehr wohl.
Bsp.: http://stackoverflow.com/questions/2163829/how-do-i-rotate-a-picture-in-c-sharp
Habe sie jetzt relativ spät gelesen
Gelesen vielleicht, aber auf keinen Fall verstanden. Die Antwort enthält bereits alles was Du brauchst. VIelleicht solltest Du einfach nochmal genauer lesen...
Eventuell ist das TableLayout-Panel für Deinen Zweck geeigneter als die Verwendung von Anchor/Docking...
Viele Wege führen nach Rom - hier ist einer davon:
Leite eine eigene Button-Klasse ab und überschreibe dort die relevanten Methoden. Etwa so:
public class MyButton : Button
{
private string _savedText = "";
protected override OnHandleCreated()
{
base.OnHandleCreated();
_savedText = Text;
}
protected override OnMouseEnter()
{
base.OnMouseEnter();
Text = _savedText;
}
protected override OnMouseLeave()
{
base.OnMouseLeave();
_savedText = "";
}
}
So ganz verstehe ich Deine Frage nicht. Das von Dir geschilderte Verhalten ist doch vollkommen logisch und nachvollziehbar. await und async sind ja gerade auch dazu da, dass Deine Anwendung nicht blockiert (also 'weiterläuft').
Wenn es Dir auf die Reihenfolge ankommt, musst Du das eben komplett anders angehen...
Du musst DevExpress mitteilen, dass die Rahmen der Fenster mit dem aktuellen Skin dargestellt werden sollen. Am besten geht das indem Du bereits in Deiner programm.cs folgendes ergänzt:
DevExpress.XtraEditors.WindowsFormsSettings.EnableFormSkins();
Wenn der FormBorderStyle auf None gesetzt wird, kommt man mit dem überschreiben der folgenden Methoden des Forms schon ziemlich weit:
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
SendToBack();
}
protected override void OnDeactivate(EventArgs e)
{
SendToBack();
base.OnDeactivate(e);
}
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
SendToBack();
}
Allerdings verschwindet das Fenster beim drücken von WIN+D dann trotzdem noch. Kann man aber evtl. auch noch irgendwie abfangen...
Oder Du schreibst gleich ein Widget (Anleitungen dazu gibt's im INet)…
Du kannst auf die Ereignisse Size und Move reagieren. Allerdings verstehe ich nicht, was die 'Bildschirmauflösung' und das Layout Deines Fensters mit dem Bildschirm zu tun haben, auf dem das Fenster dargestellt wird...
Ich würde das als eigenes UserControl implementieren - dann kannst Du es gleich an verschiedensten Stellen verwenden.
Die eigentliche Implementierung ist sehr einfach - da kommst Du schon selbst drauf. Einen kleinen Tip will ich Dir noch mit auf den Weg geben:
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
mycaptionlabeloderwasauchimmer.SendToBack();
}
Wenn Du soweit bist, wirst Du auch wissen, wozu das gut ist...
Am einfachsten wäre es sicherlich den Text zuerst auf ein Bitmap zu zeichnen und dann das Bitmap auf die entsprechende Breite zu schrumpfen.
Du könntest ein entsprechendes Event bei jedem Deiner DateTimePicker abonnieren, dass immer dann gefeuert wird, wenn der User ein Datum auswählt/ändert... Welches Event das genau ist, findest Du sicher selbst heraus.
Im Designer den Button anklicken, dann im Eigenschaftenfenster auf die Events und beim Click-Event die alte Methode auswählen.
Aber ganz ehrlich - da hättest Du auch selbst drauf kommen können...
Ohne das jetzt ausprobiert zu haben - aber das hört sich doch schon reichlich seltsam an. Ich denke, da liegt das Problem ganz woanders. Ohne Deinen Code zu kennen, kann man dazu aber nichts sagen.
Mal abgesehen davon, warum verwendest Du nicht System.Net.WebClient anstatt des Webbrowser-Controls, wenn Du sowieso keine visuelle Repräsentation benötigst?
Dann stelle ich die Frage anders:
Gibt es eine Möglichkeit innerhalb der Schleife abzufragen ob eine Taste gedrückt wurde?
Ums mal ganz reduziert zu sagen: Nein. Aber die Frage zeigt schon, dass Du es komplett falsch angehst. Nochmal der Tip: Beschäftige Dich zuerst mal systematisch mit den Grundlagen (z.B. Gallileo OpenBook CSharp).
Paint und KeyDown sind Ereignisse. Auf die Reihenfolge der Abarbeitung dieser hast Du als Entwickler keinen Einfluss.
Dir fehlen die Grundlagen bezüglich ereignisgesteuerter Programmierung scheinbar komplett. Ich denke, Du solltest Dich damit erstmal näher befassen. Dein Ansatz ist so komplett falsch, dass es nicht lohnt, daran 'herumzudoktern'.
Mal die Frage nach der Sinnhaftigkeit eines solchen Vorhabens aussen vor gelassen:
Du kannst den Parent eines vorhandenen Fensters, dessen Handle Du hast mit Hilfe der Funktion SetParent aus der user32.dll ändern:
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
Ob das auch mit einem TabControl funktioniert, musst Du selbst probieren.
Und wo genau ist Dein Problem?
Wenn die Daten auf einem Webserver liegen sollen, kannst Du jedes beliebige Dateiformat verwenden um es z.B. via FTP auf dem Server abzulegen und dann z.B. via HTTP aus Deiner Anwendung heraus wieder herunterzuladen.
Schau Dir mal die Themen XML und Serialisierung von Objekten genauer an - ich denke, dann kommst Du schon auf eine einfache Lösung...
Warum eine RichTextBox?
Nimm besser eine TextBox, bei der Du Multiline auf True setzt. RichTextBox-Controls werden zu Darstellung von formatiertem Text verwendet.
Nun zu Deinem Code:
richTextBox2.Text = Gelesene;
Damit sorgst Du dafür, dass immer nur die zuletzt gefundene Zeile angezeigt wird. Ich denke mal, das soll so nicht sein. Du musst die gefundene Zeile dem bereits vorhandenen Text hinzufügen:
richTextBox2.Text += Gelesene+"\r\n";
Wozu soll Deine Variable zeile gut sein?
Alles in allem machst Du Dir die Sache viel zu schwer. Wenn die Textdateien, die Du durchsuchen möchtest nicht allzugroß sind, kommst Du so besser:
string[] ergebnis = System.IO.File.ReadAllLines(pfad).Where<string>((zeile) => zeile.Contains(textBox1.Text)).ToArray<string>();
Outlookbar dürfte sein, was Du suchst...
24:00 Uhr gibt es nicht. Der Tag endet 23:59:59. Mit der nächsten Sekunde beginnt schon der neue Tag. Insofern ist das Ergebnis, dass Du bisher bekommst völlig korrekt.
@FZelle
Das XtraTreeList unterstützt Databinding. Eventuell könntest Du ja ein z.B. DataTable in Deinem Thread laden und dann dieses an das Control binden, statt die Nodes direkt zu erzeugen.
@wichedcsharper
Ich nutze DevExpress seit einiegn Jahren. Aus meiner Sicht lohnt sich der Einarbeitungsaufwand allemal (aber bitte nicht mit einer Schulung - die könnte entweder nur sehr oberflächlich auf die Möglichkeiten eingehen oder würde etliche Wochen dauer - besser learning by doing. Man braucht ja nicht von anfang an sämtliche Features). Schau Dir die Demos an (wurde ja schon vorgeschlagen) um Anregungen zu bekommen und dann leg einfach mal los - ist alles halb so wild... Belohnt wirst Du mit Komponenten, die alles was ich so bisher gesehen habe (und das sind alle bekannten GUI Komponenten der größeren Hersteller wie Telerik, Infragistics, Componentone etc.) quantitativ und vor allem qualitativ in den Schatten stellen. Richtig ist aber auch was FZelle sagte, bei DevExpress funktioniert manches ein wenig 'anders' als das was man so standardmässig kennt...
Ich vermute fast, dass die Zeile OpenFileDialog(); Dein wahres Problem ist. OpenFileDialog ist eine Klasse. Du musst also erstmal ein Objekt dieser Klasse erzeugen, bevor Du den Dialog anzeigen kannst. Etwa so
using (OpenFileDialog dlg = new OpenFileDialog()) {
if (dlg.ShowDialog(parent) = DialogResult.OK) {
// hier dann z.B. die ausgewählte Datei öffnen
}
}
Möglich vielleicht, aber alles andere als sinnvoll. Eine CheckedListbox ist kein ControlContainer. Früher oder später wirst Du mit einer solchen Vorgehensweise arge Probleme bekommen.
Ordne die Buttons also AUSSERHALB der Listbox gescheit an. Wenn Du eine optische Gruppierung haben möchstest, könntest Du z.B. die Controls allesamt in ein Panel packen, bei der Listbox den Border auf none stellen und dann ggf. dem Panel einen entsprechenden Hintergrund verpassen und von mir aus auch noch einen Rahmen drumherum zeichnen.
Axialis Iconworkshop verwende ich seit Jahren. Kann ich nur wärmstens weiterempfehlen...
Hast Du jetzt zu der Fehlermeldung noch eine Frage, oder warum postest Du die hier? Die Ursache dürfte ja klar sein, wenn nicht, ließ den Thread noch mal von anfang an durch...
Vergiß das FlowLayoutPanel. Ist für Deinen Zweck ungeeignet. Nimm statt dessen ein normales Panel und dann das schon angesprochene Dock.Top.
Aber noch was: Warum willst Du das Rad nochmal erfinden. Derartige Lösungen gibt es doch schon zur genüge (http://sourceforge.net/projects/dockpanelsuite/, http://www.codeproject.com/KB/vb/OutlookBar.aspx etc.)
Oder eben eine fertige Lösungen von DevComponents, DevExpress und wie sie alle heißen...
Hallo Bennibaer87,
Du solltest nicht an den Symptomen 'rumdoktern' sondern die Ursache(n) beheben. In de OnLoad des Fensters solltest Du niemals andere Fenster aufrufen/anzeigen (hier Deine MessageBox und Dein openfiledialog). Eine Lösung wurde ja schon vorgeschlagen...
Gruß,
wcseller
private void btn_sendtext_Click(object sender, EventArgs e) { Form1 frm_main = new Form1(); frm_main.richTextBox1.AppendText("SECOND_FORM\n"); }
Du erzeugst in dieser Methode jedesmal eine neue Instanz Deiner Klasse Form1 anstatt auf eine bestehende Instanz zuzugreifen. Diese neu erzeugte Instanz zeigst Du aber (zumindest soweit aus Deinem Code ersichtlich) niemals an.
Den Rest findest Du hinter dem bereits erwähnten Link.
Gruß,
wcseller
Ok, dann vllt. etwas ausführlicher:
Ich würde statt des Panels ein UserControl erzeugen, dass bereits alle notwendigen weiteren Controls enthält. Auf dieses UserControl lässt sich dann sehr wohl eine Region legen. Z.B. so (der Einfachheit halber hier mal eine elliptische Region):
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
GraphicsPath path = new GraphicsPath();
path.AddEllipse(10, 10, Width - 20, Height - 20);
Region = new Region(path);
}
Gruß,
wcseller
Hallo Funkrusha,
keine Lösung, aber ein Tip: Ich verwende für die Anzeige von PDF und vielen anderen Dateien/Formaten Oracle Outside In (speziell Data Access s.a. http://www.oracle.com/us/technologies/embedded/025613.htm) - vielleicht wäre das ja auch was für Dich...
Gruß,
wcseller
Hallo Erik Semt,
Du kannst sehr wohl einem Control eine beliebige Form geben. Schau Dir mal die Eigenschaft Region genauer an:
Gruß,
wcseller
Schöne Lösung, die aber nur funktioniert, wenn der Anwender die Größe des Fensters nicht verändert, solange der ausgeblendete Inhalt angezeigt wird. Ich würde also noch die entsprechenden Events abfangen um das Ändern der Fenstergröße zumindest für diesen Zeitraum zu unterbinden.
Gruß,
wcseller
Wenn das Panel nicht verschiebbar ist, könnte man alternativ auch mit einem Hinetrgrundbild für das Panel arbeiten, dass man aus einem Screenshot des darunter liegenden Bereiches erstellt und dann z.B. mit einem teiltransparenten Brush "übermalt".