asc schrieb:
Nein, GDI wird von WPF nicht mehr verwendet (WPF baut komplett auf DirectX auf, und verwendet auch die Win32 API nicht mehr).
Nur innerhalb des Client bereichs, die Window Titelleiste und die Minimieren, Maximieren und Schließen Buttons werden auf den alten Wege gezeichnet.
@Fresh0razoR
Für alle Controls kannst du ein Style festlegen:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Nun sind alle Controls per Default im Luna style, auch unter Windows XP.
Das wird aber nicht empfohlen, eine Applikation sollte stets so aussehen wie das Window Theme es vor gibt.
Den Fensterramen kannst du selber nicht beeinflussen, was du machen kannst ist ein Rahmenloses Fenster zu machen (WindowStyle = None) und den Rahmen sowie die System Buttons in WPF Selber zu zeichnen, dann musst du dich aber um alles selber kümmern.
Wenn du mit der WinApi vertraut bist kannst du dich auch in den Fenster WinApi Handle hooken, da hast du dann alle WinApi Möglichkeiten:
public class CustomWindow : Window
{
protected override void OnSourceInitialized(EventArgs e)
{
var handle = (new WindowInteropHelper(this)).Handle;
HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(WindowProc));
base.OnSourceInitialized(e);
}
private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case 0x0024:
//WmGetMinMaxInfo(hwnd, lParam); //Just an example
handled = true;
break;
}
return (IntPtr)0;
}
}
Benutzung dann:
namespace DemoApp
{
public partial MyWindow : CustomWindow
{
public MyWindow1()
{
InitializeComponent();
}
}
}
<Custom:MyWindow x:Class="DemoApp.MyWindow" xmlns:Custom="clr-namespace:DemoApp">
</Custom:MyWindow>
//Edit: Demo Code ausgebessert ^^
Hallo zusammen,
Kennt jemand ein freies Chart Control, dass auch bei großen Datenmengen noch schnell ist?
Ich spreche von 20 Graphen á 4000 Werten, die sich mit 25 fps ändern müssen.
Hatte bis jetzt ZedGraph benutzt, wirklich cooles Teil. Aber die Geschwindigkeit ist bei meinen Rahmenbedingungen einfach zu niedrig.
IMHO kommt man bei diesen Bedingungen nicht an DirectX vorbei. Ich habe meine Anwendung einem ausgiebigen Profiling unterzogen und der Flaschenhals ist wirklich das Neuzeichnen der Graphen per GDI+.
using(var fileStream = new FileStream)
{
...
}
using baut um Instanzen von Klassen die IDispoable implementieren automatisch einen try-finally -Block in dessen finally -Zweig Dispose() aufgerufen wird. Spart also eine gute Menge (lästige) Tipparbeit.
Ganz unten findest du Code zum Ausgeben der Cookiedaten.
http://www.codeplanet.eu/tutorials/csharp/4-tcp-ip-socket-programmierung-in-csharp.html?start=5
Ist denn nicht ohnehin jede hier gestellte Frage (mehr oder weniger) eine Übungsaufgabe von/für Anfänger bzw. Fortgeschrittene? Ich will gern dem einen oder anderen bei seinem/n Problem(ch)en helfen (so ich kann). Ich verweigere aber jegliche Zeitverschwendung in die Lösung irgendwelcher "herbeigesuchter" Aufgaben, um später meine Lösung mit der des Aufgabenstellers zu vergleichen.
Warum ich Q-Tips mag? Weil es die einzigen Tipps sind, die nicht für'n Arsch sind ...
Guten Morgen
Brauche nocheinmal eure Hilfe:
Beim laden der Statistik Form wird dies aufgerufen:
private void InitChartAktuell(ZedGraphControl zgc)
{
myPane = zgc.GraphPane;
myPane.CurveList.Clear();
//Titel
myPane.Title.Text = "Statistik " + IQuizPanel.IHauptprogramm.IBenutzerInfo.benutzername;
myPane.Title.FontSpec.Size = 20;
//X Labels
myPane.XAxis.Title.FontSpec.Size = 15;
myPane.YAxis.Title.Text = "Anzahl";
myPane.YAxis.Title.FontSpec.Size = 15;
try
{
//XLabels
string[] XLabels = { "Übungstag: " + DateTime.Now.ToShortDateString () };
myPane.XAxis.Type = AxisType.Text;
myPane.XAxis.Scale.TextLabels = XLabels;
myPane.XAxis.Scale.FontSpec.Size = 15;
//Y Labels
myPane.YAxis.Type = AxisType.Exponent;
myPane.YAxis.Scale.FontSpec.Size = 15;
myPane.YAxis.Scale.FontSpec.IsBold = true;
//Refresh
zgc.AxisChange();
zgc.ZoomOutAll(myPane);
zgc.Refresh();
}
catch (Exception)
{ }
}
Via Menü hat der User die Möglichkeit die anderen Statistiken anzeigen zu lassen:
private void aktuelleStatistikToolStripMenuItem_Click(object sender, EventArgs e)
{
if (activChart == 0)
{
UpdateChartAktuell(zedGraphControl1);
return;
}
LangzeitanzeigenToolStripMenuItem.Enabled = true;
AktuellanzeigenToolStripMenuItem2.Enabled = false;
FachbereichanzeigenToolStripMenuItem1.Enabled = true;
SchwierigkeitToolStripMenuItem.Enabled = true;
InitChartAktuell(zedGraphControl1);
activChart = 0;
}
private void langzeitstatistikAnzeigenToolStripMenuItem_Click(object sender, EventArgs e)
{
if (activChart == 1) return; //evtl. neu zeichnen ?
myPane.CurveList.Clear();
LangzeitanzeigenToolStripMenuItem.Enabled = false;
AktuellanzeigenToolStripMenuItem2.Enabled = true;
FachbereichanzeigenToolStripMenuItem1.Enabled = true;
SchwierigkeitToolStripMenuItem.Enabled = true;
InitChartLangzeit(zedGraphControl1);
activChart = 1;
}
usw...
Hier der Code zur Langzeitstatistik:
public void InitChartLangzeit(ZedGraphControl zgc)
{
if (XMLStatistik == null) return;
if (structlist == null) structlist = new List<statistikstruct>();
zgc.Invalidate();
zgc.GraphPane.GraphObjList.Clear();
List<String> zeitpunkte = new List<string>();
//Alle Daten (Datums) in eine Liste holen
foreach (XmlNode dateNode in XMLStatistik.DocumentElement.ChildNodes) if (zeitpunkte.Contains (dateNode.FirstChild.InnerText) == false) zeitpunkte.Add (dateNode.FirstChild.InnerText);
foreach (String zeitpunkt in zeitpunkte)
{
statistikstruct s = new statistikstruct();
s.datum = zeitpunkt;
foreach (XmlNode node in XMLStatistik.DocumentElement.ChildNodes)
{
//Wenn Datum übereinstimmt - richtig und falsch zusammenzehlen
if (node.FirstChild.InnerText != zeitpunkt) continue;
else
{
s.richtig = s.richtig + Convert.ToInt16(node.ChildNodes[1].InnerText);
s.falsch = s.falsch + Convert.ToInt16(node.ChildNodes[2].InnerText);
}
}
structlist.Add(s);
}
myPane = zgc.GraphPane;
//Needed for redrawing the chart, to remove old curves
//myPane.CurveList.Clear();
// Set the title and axis labels
myPane.Title.Text = "Langzeitstatistik " + IQuizPanel.IHauptprogramm.IBenutzerInfo.benutzername;
myPane.XAxis.Title.Text = "Datum der Bewertung";
myPane.YAxis.Title.Text = "Falsch / Richtig";
// Make up some data points
string[] labels = zeitpunkte.ToArray();
List<double> ri = new List<double>();
List<double> fa = new List<double>();
foreach (statistikstruct s in structlist)
{
ri.Add(s.richtig);
fa.Add(s.falsch);
}
double[] y2 = ri.ToArray();
double[] y = fa.ToArray();
// Generate a red bar with "Curve 1" in the legend
BarItem myCurve = myPane.AddBar("Falsch", null, y, Color.Red);
// Fill the bar with a red-white-red color gradient for a 3d look
myCurve.Bar.Fill = new Fill(Color.Red, Color.White, Color.Red);
// Generate a blue bar with "Curve 2" in the legend
myCurve = myPane.AddBar("Richtig", null, y2, Color.LimeGreen);
// Fill the bar with a Blue-white-Blue color gradient for a 3d look
myCurve.Bar.Fill = new Fill(Color.LimeGreen, Color.White, Color.LimeGreen);
// Draw the X tics between the labels instead of at the labels
myPane.XAxis.MajorTic.IsBetweenLabels = true;
// Set the XAxis to Text type
myPane.XAxis.Type = AxisType.Text;
// Set the XAxis labels
myPane.XAxis.Scale.TextLabels = labels;
//myPane.XAxis.Scale.FontSpec.Size = 10;
// Set the bar type to stack, which stacks the bars by automatically accumulating the values
myPane.BarSettings.Type = BarType.Stack;
// Calculate the Axis Scale Ranges
zgc.AxisChange();
zgc.ZoomOutAll(myPane);
zgc.Refresh();
}
Das Problem ist nun, das bei einem Wechsel von einer Statistik zur anderen, die alte Statistik nicht gelöscht, sondern die neue angehängt wird. Wie umgehe ich das ?
Hallo,
hast du denn auch die Eigenschaft DataPropertyName der ComboBoxColumn gesetzt?
Ansonsten sollte es eigentlich funktionieren, s.a. How to: Bind Objects to Windows Forms DataGridView Controls
Ja nicht nur in der Sprache, anscheint auch in der Deutschen Sprache.
Dein Satzbau und deine Worte sind etwas wirr.
Du willst also ein vorhandenes Bild in einen 30x30 Ausschnitt kopieren und diesen dann woanders einfügen?
Dann brauchst du das MouseDown Event. Dort musst du überprüfen ob es die Linke-Maustaste ist, welche gedrückt wurde. Wenn ja musst du überprüfen das du innerhalb des Images bist, danach schneidest du einfach ausgehend von der Position wo du dich befindest einen 30x30 ausschnitt aus. Achte aber darauf das du nicht aus den Grenzen des Bildes schneidest.
Es gibt es nichts "frei zu geben".
TextBoxen haben diese Funktionalitäten bereits, da musst du nichts machen.
Aber bei ListBoxen und anderen Controls gibt es das per Default nicht, denn
-> Was soll kopiert werden?
-> Wie?
-> Alles was irgendwie selektiert ist?
-> Wann gilt etwas als selektiert?
-> Wie können komplexe Objekte in die Zwischenablage?
Schnapp dir die entsprechenden ApplicationCommands und implementiere es selber für die anderen Controls..
ArrayList ist völlig veraltet, nimm gleich eine typisierte List<..>, und du hast die Casting-Probleme nicht mehr...
Und um 'Structs' (also Werttypen) zu ändern, mußt du erst die komplette Struktur lokal in einer Variable speichern, dann den einzelnen Wert ändern und danach wieder die komplette Struktur wegspeichern (solltest du dies öfter machen, würde ich dir empfehlen, daraus eine Klasse (Referenztyp) zu machen).