Laden...

Forenbeiträge von Marauder1986 Ingesamt 29 Beiträge

16.05.2011 - 10:51 Uhr

Man kann die Session-Gültigkeit setzen, ob's das ist weiß ich aber nicht genau.

<sessionState timeout="20" />

Ich entsinne mich daran, selbst auch mal das Problem gehabt zu haben, kenn die Lösung aber nicht mehr 🤔 (spontan fallen mir als Verdächtigen ein: ein Eintrag in der Windows-Registry oder eine Einstellung direkt im IIS).

Aber vieleicht hilft dir ja der erste Tipp weiter.

Grüße,
Julian

03.06.2009 - 12:22 Uhr

Danke Khalid - das war doch mal eine konstruktive antwort.
Also zum Thema Administration etc.:
Der TFS 2008 ist bereits eingerichtet und läuft erfolgreich (hab einen WHS, worauf sich der TFS erfolgreich installieren ließ - Athlon64 3000+ mit 4GB Ram - für meine Anforderungen sicherlich ausreichend).

Dass es keine echten 1-Mann Templates gibt, hatte ich mir schon gedacht (aber man weiß ja nie 😉 ). Es kann ja auch ein "klassisches" Teamtemplate sein (da bin ich halt Projektleiter, Entwickler etc. in einer Person). Nur die mitgelieferten Templates haben für einen Einzelentwickler doch sehhhr viel Overhead - jedenfalls erscheint es mir so.

Ich habe auch mal im MSDN und CodePlex durchgeguckt nach Templates, hab da aber den Wald vor Bäumen nicht mehr erkannt.
Vieleicht kannst du ja einen kurzen Umriss über dir bekannte, einfach gestrickte Templates geben?
Der Tipp mit der Buchlektüre klingt gut - da schau ich mich mal um. Oder hat sich da auch bereits eine Art "Gebetsbuch zum TFS" etabliert (darf selbstverständlich auch auf Englisch sein - ist eh meist besser zu lesen)?

Thx

03.06.2009 - 11:53 Uhr

Hallo iced-t89

Mir ist schon klar, dass das Team System für Entwicklerteams gedacht ist.
Aber ich habe eingangs auch erwähnt dass ich es nutzen möchte, um das VSTS kennen zu lernen. Außerdem denke ich (sagen wir besser, ich erhoffe es mir), dass auch ein Einzelkämpfer einige Vorteile aus dem VSTS ziehen kann.

Im übrigen (ist jetzt nicht böse gemeint) lautete meine Frage nicht, ob es sinn macht, Team System zu nutzen, sondern ich habe nach Tipps und Hinweisen zu einem passenen Template gefragt.

Aber ich mach's gern nochmal deutlicher:
Primärer Grund ist wie gesagt, dass ich mich einfach mit dem Team System, dessen Verwendung etc. vertraut machen möchte - quasi zu Studienzwecken.
Weitere Mehrwerte, die ich mir davon dann noch erhoffe:
Versionsverwaltung (dafür braucht es ja definitiv kein Team, um sie sinnvoll zu nutzen) sowie die Möglichkeit, meine Aufgaben besser zu sortieren.
Außerdem arbeite ich im moment immer noch einfach drauf los. Das möchte ich eben durch einen Entwicklungsprozess etwas ordnen bzw. professioneller angehen.

Vieleicht ist es nun alles etwas deutlicher...
Trotzdem danke für deine (wenn auch wenig hilfreiche) Antwort.

03.06.2009 - 11:24 Uhr

Hallo allerseits!
Da unsere Hochschule einen MSDN Academic Alliance Zugang bietet, hab ich Zugang zur Vollversion des VS Team System und dem TFS. Diesen möchte ich nun für mich privat einstetzen, um mich mit dem TFS vertraut zu machen.
Ich entwickle alleine, hauptsächlich Websites (auch komplexere) und kleinste .NET Tools.
Nun stellt sich mir die Frage, wie ich den TFS für mich einsetze. Ich will das auf jeden Fall richtig einsetzen und nicht nur "rumspielen", außerdem möchte mich nicht nur auf die Quellcodeverwaltung beschränken.
Gibt es Entwicklungsprozesse und TFS Vorlagen, die gut für ein 1-Mann-Team geeignet sind, ohne unnötig überladen zu sein?
Außerdem bin ich mir nicht sicher, ob ich für mich ein Team Project anlege und dort alle meine Projekte hineinpacke, oder für jedes größere Projekt ein neues TFS Projekt anlege?

Vieleicht hat ja einer von euch Erfahrungswerte, wie man den TFS alleine sinnvoll einsetzen kann.
Thx
Julian

26.05.2009 - 11:46 Uhr

Danke für deine ausführliche Antwort 😃
Das Html statuslos ist ist mir bewusst und so - aber dank Ajax und Viewstate etc. hat sich das ja doch sehr relativiert.
Zum besseren Verständniss einmal der Sinn der Sache:
Ich habe eine Seite mit recht komplexen Layout und zusätzlich vielen Bildern.
Außerdem läuft die Navigation über Ajax.
Nun möchte ich, dass jede Seite (genauergesagt, das entsprechende UpdatePanel) erst komplett beim Client geladen wird, bevor sie Angezeigt wird. Solange soll ein Ladehinweis erscheien.
Nun gibt es ja das Control UpdateProgress, welches sich aber leider nur auf die Arbeitszeit beim Server beschränkt. In diesem UpdateProgress möchte ich eben auch die Downloadzeit der Bilder einbeziehen.
So - Das ist mein Problem - ich bin auch gerne für andere Lösungsansätze offen.

P.S.: Die Lösung, einfach mit einem simplen JavaScript beim ersten Besuch alle Bilder zu laden ist keine (habe ich bereits probiert). Begründung: Die Ladezeit ist u. U. bei einer langsamen Verbindung schlicht zu lange. Daher möchte ich die Ladezeiten auf jeden Request aufteilen und somit subjektiv minimieren.

25.05.2009 - 15:57 Uhr

Hallo Leute
möchte mir gerne ein ASP.NET Control erstellen, welches Bilder beim Client lädt und ein Event feuert, wenn alle Bilder geladen sind.
Die Handhabung sollte vergleichbar mit dem Timer Control sein.
Nun bin ich irgendwie mit den vielen Möglichkeiten in ASP.NET, AJAX Controls zu erstellen, hoffnungslos überfordert.
Wenn das ganze dingen fertig ist, sollte es sich im Code einer Seite etwa so einbinden lassen:


ImageLoader loader = new ImageLoader();
loader.Files.Add("/Bild1.jpg");
loader.Files.Add("/Bild2.gif");
// .......
// event wenn alle Bilder _beim Client_ heruntergeladen sind.
loader.LoadComplete += new EventHandler<EventArgs>(imagesLoaded);
loader.Enabled = true;

Danke für alle Tipps

18.12.2008 - 14:52 Uhr

Ja die Befürchtung hatte ich dass es euch so gehen wird 🤔

Aber ich glaube mir ist eben aufgefallen was der Fehler wirklich sein könnte:
In der MidiInProc dürfen nur bestimmte Funktionen aufgerufen werden, und midiInAddBuffer gehört laut MSDN nicht dazu...

Nun daher eine andere Frage:
Wie kann ich eine Funktion einer Klasse so aufrufen, dass sie in dem Thread ausgeführt wird, in dem die Klasse erstellt wurde )(wie z.B. bei den WinForms die Invoke() Methode)? Mit einem delegate hab ich's eben probiert, dann wird die Methode aber im selben Thread ausgeführt...

18.12.2008 - 14:23 Uhr

Hallo allerseits

Titel ist etwas unpassend, aber mir viel nix treffenderes ein...

Ich habe mal wieder mein Midi-Projekt ausgekramt, welches das Midi-API aus der Winmm.dll nutzt. Für einfache Midi-Nachrichten (Empfang) geht das auch alles bombig - seit ich aber den Empfang von SysEx Nachrichten implementiert habe passiert nach der 3. oder 4. empfangenen SysEx-Nachricht nix mehr (im besten Fall) oder die Applikation raucht komplett ab (und das ohne dass der Debugger meckert - der stopt einfach nur und bekommt von allem nix mit).

Für den Empfang von SysEx Nachrichten benötigen die Winmm.dll einen Buffer - und ich schätze das ist der Punkt an dem ich irgendwas grundlegend falsch gemacht habe. Die Rückgabewerte der API-Funktionen melden jedenfalls keine Fehler.
Jetzt habe ich etwas Angst hunderte Zeilen Quelltext zu posten und dünn das mal alles extrem aus - wenn wem was fehlt melden, dann kommt der entsprechende Code nach


public class InputDevice : MidiDevice
{
	delegate void MidiInDelegate(int hMidiIn, MidiInProcMessage wMsg, int dwInstance, int dwParam1, int dwParam2);
	MidiInDelegate midiInProc;

	// ... more fields ...
	MidiSysExHeader sysExBufferHeader;

	public InputDevice(int id)
	{
		this.id = id;
		midiInProc = MidiInProc;

		// Create a sysex buffer
		// sysExBufferHeader.lpData is freed in Close()
		sysExBufferHeader = new MidiSysExHeader();
		sysExBufferHeader.lpData = Marshal.AllocHGlobal(0xFFFF);
		sysExBufferHeader.dwBufferLength = 0xFFFF;

		// ... more init ...
	}

	void MidiInProc(int hMidiIn, MidiInProcMessage wMsg, int dwInstance, int dwParam1, int dwParam2)
	{
		EventHandler<MidiEventArgs> handler = null;
		MidiEventArgs e = new MidiEventArgs();
		switch (wMsg)
		{
			case MidiInProcMessage.LongData:
				if (sysExBufferHeader.dwBytesRecorded <= 0)
					break; // Ignore empty buffer
				System.Diagnostics.Debug.WriteLine("MIDI In (" + this.productName + "): " + wMsg.ToString());

				handler = SysExMessageReceive;

				// Building up a sysex message
				byte[] data = new byte[sysExBufferHeader.dwBytesRecorded];
				Marshal.Copy(sysExBufferHeader.lpData, data, 0, sysExBufferHeader.dwBytesRecorded);
				e.MidiMessage = new SystemExclusiveMessage(data);
				NativeMethods.midiInAddBuffer(handle, ref sysExBufferHeader, 48);
				break;
			// ... more cases that work fine ...
			default:
				break; // ignore unknown message
		}

		// Throw the event
		if (handler != null)
			handler(this, e);
	}

	public override void Open()
	{
		MMRESULT result;
		if (!isOpen)
		{
			result = NativeMethods.midiInOpen(
				out handle,
				id,
				midiInProc,
				0,
				CallbackType.Function
			);
			if (result != MMRESULT.NoError)
				throw new MidiException(ErrorText(result));
			isOpen = true;
		}
		if (!isStarted)
		{
			result = NativeMethods.midiInStart(handle);
			if (result != MMRESULT.NoError)
				throw new MidiException(ErrorText(result));
			NativeMethods.midiInPrepareHeader(handle, ref sysExBufferHeader, 48);
			NativeMethods.midiInAddBuffer(handle, ref sysExBufferHeader, 48);
			if (result != MMRESULT.NoError)
				throw new MidiException(ErrorText(result));
			isStarted = true;
		}
	}
	// ... more code ...
}

Mhh, ist jetzt auch schon reichlich...
Wer alles sehen will - die komplette Klasse ist im Anhang.

10.12.2008 - 13:33 Uhr

Hallo allerseits.
Zunächst: Leider ist der Titel etwas ungeeignet, mir viel nichts besseres ein. Vieleicht gibts ja auch schon ein passendes Thema dazu, was mir mangels treffender Stichworte durch die Lappen gegangen ist - sorry schon mal wenn dem so ist 😉
Ich möchte ein Control entwickeln, tappe allerdings absolut im dunkel wie ich dazu ansetze (meine jetzt nicht die allgemeine Methodik für Usercontrols - dazu gibts Bücher und Tutorials - sondern die Entwicklung auf das Problem bezogen).

Also, brauch ein Control, dass sich prinzipiell erstmal verhält wie eine normale RichTextBox, allerdings mit einger Besonderheit:
Zu jeder Textzeile lassen sich Objekte (Text, kleine Bilder, oder gar andere Controls, weiß noch nich so genau) hinzufügen, besser gesagt "anheften". Mit anheften meine ich, dass jedes Objekt unmittelbar über einem Buchstaben klebt - editiert man den Text vor dem Zeichen wo es angeheftet ist, wandert es also entsprechend mit - löscht man das zeichen heftet sich das Objekt an das nebenstehende Zeichen.
Die Objekte sind im übrigen nicht direkt editierbar (abgesehen von verschieben und löschen).

Zum genaueren Verständnis hier der Hintergrund:
Ich arbeite an einem Programm, um Leadsheets zu schreiben. Dementsprechend müssen Akkorde, Taktstriche und andere Angaben passend an den Liedtext geheftet sein.

Vieleicht hat ja jemand von euch einen guten Ansatz als Idee???
Thx

P.S.:
Wer kein Musiker ist und sich darunter nichts konkretes vorstellen kann - ich habe mal ein Word-Dokument in den Anhang gepackt, das zeigt wie wir solche Leadsheets derzeit mit Word schreiben.
Und den Mechanismus von einrücken und schieben mit Tabs und Leerzeilen will ich eben in einem eigenen Programm automatisieren.

19.09.2008 - 09:35 Uhr

YMMD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Wow, ich bin geschockt. Schon zu Zeiten als ich noch in PHP gearbeitet habe (naja, eigentlich habe ich erst vor einem Jahr auf ASP.net umgestellt) habe ich mir immer gewünscht, Webapplikationen wie für den Desktop erstellen zu können.
Mit ASP.net dachte ich das wäre schon nah dran, aber DAS toppt alles 😁

Habe es jetzt erst installiert und mir eine erste Testpage zusammengeklickert, aber das macht einen sehr vielverpsrechenden Eindruck.

Allerdings stellt sich mir die ähnliche Frage wie dir.
Ein Verdacht von mir ist: Die Controls sind an die Technologie gebunden: So wie ich das verstanden habe, kann ich nur speziell für VWG erstellte Controls verwenden, die wiederum nicht für WebForms gehen.
Abgesehen davon: Der älteste Post im Forum von VWG ist vom 15.05.2006 - das ist ja erst 2 Jahre her. Und ein OpenSource Projekt einer (zumindest mir) unbekannten Truppe muss sich auch erst mal herumsprechen...

Aber vieleicht taucht der große "Haken" ja auch noch im Laufe dieses Tages auf - ich werde es jedenfalls mal ausgiebig testen...

LG
Julian

18.09.2008 - 16:46 Uhr

Hi allerseits

Habe ein Problem mit meinem neuen TreeView (=> TreeView als DirectoryBrowser).
Aufgrund der Datenmenge fülle ich alle Knoten (außer im Wurzelverzeichnis natürlich) mit PopulateOnDemand. Das klappt auch wunderbar. Allerdings ist es mir nicht möglich, dynamisch erzeugte Knoten zu selektieren. Klicke ich auf einen Knoten, verschwinden alle dynamisch erzeugten Knoten einfach, und es wird auch kein SelectedNodeChanged-Event ausgelöst.
Für alle Knoten, dich ich beim ersten Aufruf statisch und nicht per PopulateOnDemand erzeuge, funktioniert das Selektieren.

Hat jemand einen Tipp???

P.S. Hier noch der Code der Klasse


public class FileTreeView : TreeView
{
	protected bool _showFiles;
	protected string _rootDirectory = "";

	public bool ShowFiles
	{
		get { return _showFiles; }
		set { _showFiles = value; }
	}
	public string RootDirectory
	{
		get { return _rootDirectory; }
		set { _rootDirectory = value; }
	}

	protected override void OnLoad(EventArgs e)
	{
		this.TreeNodePopulate += new TreeNodeEventHandler(FileTreeView_TreeNodePopulate);
		this.SelectedNodeChanged += new EventHandler(FileTreeView_SelectedNodeChanged);
		if (!Page.IsPostBack && Directory.Exists(_rootDirectory))
		{
			// Create top-level nodes
			DirectoryInfo rootDirectoryInfo = new DirectoryInfo(_rootDirectory);
			foreach (DirectoryInfo subDir in rootDirectoryInfo.GetDirectories())
			{
				TreeNode directoryNode = CreateDirectoryNode();
				directoryNode.Text = subDir.Name;
				directoryNode.PopulateOnDemand = false;
				foreach (DirectoryInfo subSubDir in subDir.GetDirectories())
				{
					TreeNode directoryNode2 = CreateDirectoryNode();
					directoryNode2.Text = subSubDir.Name;
					directoryNode.ChildNodes.Add(directoryNode2);
				}
				this.Nodes.Add(directoryNode);
			}
			if (_showFiles)
			{
				foreach (FileInfo file in rootDirectoryInfo.GetFiles())
				{
					TreeNode fileNode = CreateFileNode();
					fileNode.Text = file.Name;
					this.Nodes.Add(fileNode);
				}
			}
		}
	}

	void FileTreeView_SelectedNodeChanged(object sender, EventArgs e)
	{
		// !!! Passiert nur für Knoten, die in OnLoad erzeugt wurden !!!
		System.Diagnostics.Debug.WriteLine("Select node");
	}

	void FileTreeView_TreeNodePopulate(object sender, TreeNodeEventArgs e)
	{
		DirectoryInfo nodeDirectoryInfo = new DirectoryInfo(_rootDirectory + e.Node.ValuePath.Replace("/", "\\"));
		foreach (DirectoryInfo subDir in nodeDirectoryInfo.GetDirectories())
		{
			TreeNode directoryNode = CreateDirectoryNode();
			directoryNode.Text = subDir.Name;
			e.Node.ChildNodes.Add(directoryNode);
		}
		if (_showFiles)
		{
			foreach (FileInfo file in nodeDirectoryInfo.GetFiles())
			{
				TreeNode fileNode = CreateFileNode();
				fileNode.Text = file.Name;
				e.Node.ChildNodes.Add(fileNode);
			}
		}
	}

	/// <summary>
	/// Helper method to create a directory node.
	/// </summary>
	/// <returns></returns>
	protected TreeNode CreateDirectoryNode()
	{
		TreeNode directoryNode = new TreeNode();
		directoryNode.PopulateOnDemand = true;
		directoryNode.Expanded = false;
		return directoryNode;
	}

	/// <summary>
	/// Helper method to create a file node.
	/// </summary>
	/// <returns></returns>
	protected TreeNode CreateFileNode()
	{
		TreeNode fileNode = new TreeNode();
		fileNode.PopulateOnDemand = false;
		fileNode.Expanded = true;
		return fileNode;
	}
}

Die (unspektakuläre) Einbindung auf der ASPX Seite


<gs:FileTreeView ID="FileTreeView1" runat="server" RootDirectory="E:\" ShowFiles="true" />

29.03.2008 - 00:48 Uhr

Hallo Jungs & Mädels

Experimentiere grad ein wenig mit Soundprocessing rum und benutze dafür Asio.
Nun stehe ich jetzt vor folgendem, generellen Problem:
In einem Worker-Thread werden die Buffer fleißig gefüllt.
Mache ich das so


double a = 1.0;
double w1 = 2 * Math.PI * 440;
double w2 = 2 * Math.PI * 446;
t = sample / _driver.SampleRate;
_leftChannel[i] = a * Math.Sin(w1 * t);
_rightChannel[i] = a * Math.Sin(w2 * t);

klingts super. Ich erhalte eine Schwebung wie gewünscht.
So allerdings


double a = 1.0;
double w1 = 2 * Math.PI * 440;
double w2 = 2 * Math.PI * 446;
t = sample / _driver.SampleRate;
_leftChannel[i] = a * (Math.Sin(w1 * t) + Math.Sin(w2 * t));
_rightChannel[i] = _leftChannel[i];

kommt ein grausamer Sound aus den Boxen. Das gewünschte Ziel lässt sich nur erahnen. Klingt eher nach einer schwebenen Rechteck-Schwinung als einer Sinus-Schwingung.
Physikalisch sind beide Methoden ja nahezu gleich.
Ich tippe daher mal auf Rundugsfehler, welche die ungewollten Obertöne ergeben.
Aber warum tritt der Effekt nur so auf, und noch wichtiger:
Wie komm ich drum rum????

Danke und Gruß!

EDIT:
*args* Ich Vollidiot.
Das Problem sind natürlich keine Rundungsfehler, sondern die Amplitude. Der Buffer des Asiotreiber arbeitet anscheinend mit Werten zwischen -1 und 1.
Durch mein Addieren hat sich die Amplitude natürlich verdoppelt und die überlaufenden Werte werden auf 1 abgeschnitten...

Also - Thread hat sich bereits wieder erledigt ^^

13.03.2008 - 23:03 Uhr

Jau - hab auch just in diesem Moment die Lösung gefunden. Diesmal mit Hilfe der Expression Blend 2 Preview.
Ich war eigentlich schon quasi dran. Das einzige was mir fehlte war, dem Window im XAML einen Namen zuzuweisen und diesen im Binding mit anzugeben. Zusätzlich noch UpdateSourceTrigger angepasst und ein [x] in den Header gesetzt - nun habe ich mein Tabbed-Documents feature 🙂

Danke für jegliche Hilfe!!! 👍

Nun habe ich aber noch eine andere Frage:
Beim Versuch, von einer TextBox auf eine RichTextBox umzusteigen bin ich nun auf die Nase gefallen. Denn das Document Property lässt sich von .Net-Hause aus nicht Binden. Habe dafür aber ein Workaround gefunden. Der Macher davon äußert dort aber auch die Bedenken, warum diese einfache Implementierung nicht mit dem Framework kommt und ob das vieleicht übelst in die Hose gehen kann... 🤔
Weiß jemand etwas dazu???

13.03.2008 - 20:32 Uhr

Bin auch neu was WPF angeht - daher nur halbwissen.
Ich versuch aber trotzdem mal Punkte zu nennen die ich als Vorteile sehe:
Durch die einführung von XAML als Beschreibungssprache für das GUI ist Code und Oberfläche sauberer getrennt. Ein Designer arbeitet also am XAML-Code, erstellt Templates für die Controls und muss sich nicht um die Programmierung kümmern. Der Entwickler dagegen kann die vorgegeben Funktionen implementieren. Die genaue beschaffung des GUI interessiert dabei nicht.
Außerdem kann so zimlich jedes Steuerelement jeden erdenklichen Inhalt darstellen. Eine ListBox kann dann z. B. Bilder oder gar Videos enthalten, und das wie selbstverständlich. Mit den WinForms ist das ja nicht ganz trivial.

Der weitere Punkt ist (wie du selber erwähnt hast) DirectX. Das ausschlaggebene ist dabei aber wie ich finde weniger die Leistung (natürlich auch - aber sauber Programmiert läuft eine WinForms Anwenund ja auch flüssig auf normalen PCs) sondern die Möglichkeit, auch auf DirectX-Effekte (echte Transparenz, Schatten, etc) zugreifen zu können sowie 3D-Aufgaben gleich mit der GraKa zu bewälltigen.

Dann noch das Databinding (was ich leider noch nicht ganz verstanden habe, aber ich arbeite daran). Du kannst über das XAML z. B. einer ListBox eine Collection als Quelle zuweisen und automatisch sind die beiden Syncronisiert ohne dass du selber Code schreiben muss, um das zu überwachen.

Das ist das was ich nach meinen Recherchen bis jetzt so erkannt habe.
Falls irgendwas grundlegend falsch sein sollte bitte ich natürlich um Aufklärung 😁

EDIT: Da war wohl jemand schneller...

13.03.2008 - 19:03 Uhr

Nabend!

Statt den ObjectType musst du die ObjectInstance des ObjectDataProviders setzen.

Ja darauf war ich auch schon gekommen (IntelliSense sei dank g).
Aber leider ist mir bisher die nötige Syntax dazu verborgen - und das MSDN ist diesbezüglich auch etwas in Schweigen gehüllt ( MSDN-Auszug)
Denn es genauso zu versuchen wie mit ObjectType (="{x:Type src:...}" klappt nicht (und macht ja auch keinen Sinn - ist ja dann schließlich kein Typ).

Aber du solltest dir deine Templates nochmal anschaun, bzw. was die Properties ContentTemplate und ItemTemplate beim TabControl bedeuten. Beide machen nämlich nicht das was du denkst dass sie es tun

Dann müstest du mir den Unterschied erklären. Denn diesen Teil Code habe ich aus einem MSDN-Sample entnommen (http://msdn2.microsoft.com/en-us/library/aa972130.aspx) und dort (wie auch bei mir wenn ich per XAML von Hand TabItems einfüge) funktioniert es wie ich vermute 🤔

Danke für die Antworten

13.03.2008 - 15:51 Uhr

Ich spreche jetzt erst mal von mir privat:
Ich habe mir vor längerer Zeit bereits WPF angeguckt und seit letzter Woche entschieden, mich (privat) ganz dem WPF zu widmen und mich in die Technologie einzufuchsen.

Auf der Firma ist WPF allerdings kein Thema - Gründe wurden ja eigentlich bereits genannt:

  • Kosten/Nutzen einer Portierung bestehender Software ist indiskutabel
  • Software muss auch auf leistungsschwachen (Industrie-) PCs lauffähig sein - auf DX zu setzen kommt damit also ebenso wenig in Frage.
13.03.2008 - 15:16 Uhr

Hallo allerseits.

Bin neu was WPF angeht und irgendwie zweifel ich langsam an mir - ich sitz bereits Stunden daran, ein TabControl an eine Liste zu binden und bekomm es nicht hin - auch zahlreiche Google-Ergebnisse haben mir nicht geholfen (was wohl eher an mir liegen dürfte als an den Suchergebnissen ^^).

Zum Hintergrund (eig. ganz simpel):
Ich habe eine Liste, in der alle derzeit geöffneten Dateien drin sind und will mein TabControl an diese Liste binden, um damit die Dokumente anzuzeigen (vgl. alle gängigen Texteditoren wie VS, UltraEdit etc.).

Im moment sieht es so aus:


// Document.cs
class Document
{
	public string Filename
	{
		get { /*...*/ }
		set { /*...*/ }
	}
	public string Text
	{
		get { /*...*/ }
		set { /*...*/ }
	}
	/* Class implementation */
}

// MainWindow.xaml.cs
public partial class MainWindow : Window
{
	private int _newDocumentCount = 1;
	public ObservableCollection<Document> _openDocuments;

	public MainWindow()
	{
		_openDocuments = new ObservableCollection<Document>();
		Document doc = new Document();
		doc.Filename = "Untitled " + _newDocumentCount++ + ".txt";
		doc.Text = "";
		_openDocuments.Add(doc);

		InitializeComponent();
	}
}

MainWindow.xaml (auszug)


<Window.Resources>		
		
	<DataTemplate x:Key="DocumentTabHeader">
		<TextBlock Text="{Binding Path=Filename}" />
	</DataTemplate>
	
	<DataTemplate x:Key="DocumentTabContent">
		<TextBox SpellCheck.IsEnabled="True" Text="{Binding Path=Text}" />
	</DataTemplate>
</Window.Resources>
<!-- .......... -->
<TabControl ItemsSource="{Binding Source=_openDocuments}" ItemTemplate="{StaticResource DocumentTabHeader}" ContentTemplate="{StaticResource DocumentTabContent}"
/>

Das Instanziieren eines Typs mittels ObjectDataProvider wie im MSDN beschrieben klappt ja wunderherlich - aber direkt auf eine im Code implementiertes Variable zugreifen bekomm ich einfach nich hin...

Wär für jede Hilfe (auch für WPF-Einsteiger geeignete Links) dankbar.

EDIT: Hab ich doch glatt vergessen, das eigentliche Problem zu erwähnen:
Wenn ich mein Programm aufstarte, habe ich direkt 14 (???) Tabs bei denen sowohl Text als auch Header leer ist.

10.09.2007 - 11:50 Uhr

Kannst du mal den ganzen Code deines Controls posten?

Sollst du haben! 😉


public partial class ExtendedControl : UserControl
{
	#region Private fields

	// Buffering
	private Bitmap buffer;
	private Graphics bufferGraphics;

	// Background variables
	private Color backColor1;
	private Color backColor2;
	private JG.CustomControls.BackgroundStyle backgroundStyle;

	// Border variables
	private Color borderColor;
	private System.Drawing.Drawing2D.GraphicsPath borderLine;
	
	#endregion
		

	#region Designer properties

	[Category("Appearance")]
	public JG.CustomControls.BackgroundStyle BackgroundStyle
	{
		get	{ return this.backgroundStyle;  }
		set { this.backgroundStyle = value; }	
	}

	[Browsable(false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	public override Color BackColor
	{
		get
		{
			return base.BackColor;
		}
		set
		{
			this.backColor1 = value;
			base.BackColor = value;
		}
	}
	
	[Category("Appearance")]
	public Color BackColorPrimary
	{
		get
		{
			return this.backColor1;
		}
		set
		{
			this.backColor1 = value;
		}
	}

	[Category("Appearance")]
	public Color BackColorSecondary
	{
		get
		{
			return this.backColor2;
		}
		set
		{
			this.backColor2 = value;
		}
	}

	#endregion
	

	#region Code properties

	#endregion

	public ExtendedControl()
	{
		this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
		this.ResetBuffer();

		InitializeComponent();
	}

	public ExtendedControl(IContainer container)
	{
		container.Add(this);

		InitializeComponent();
	}

	private void ResetBuffer()
	{
		if (this.buffer != null)
		{
			this.buffer.Dispose();
		}
		if (this.bufferGraphics != null)
		{
			this.bufferGraphics.Dispose();
		}
		int Width = 1, Height = 1;
		if (this.Width > 1)
		{
			Width = this.Width;
		}
		if (this.Height > 1)
		{
			Height = this.Height;
		}
		this.buffer = new Bitmap(Width, Height);
		this.bufferGraphics = Graphics.FromImage(this.buffer);
		this.Invalidate();
	}


	protected override CreateParams CreateParams
	{
		get
		{
			CreateParams cp = base.CreateParams;
			cp.ExStyle |= 0x20;
			return cp;
		}
	}

	protected override void OnPaintBackground(PaintEventArgs e)
	{
		bufferGraphics.Clear(Color.Transparent);
		bufferGraphics.FillRectangle(
		    new SolidBrush(this.backColor1),
			0, 0, this.Width - 1, this.Height - 1);
		e.Graphics.DrawImageUnscaled(buffer, Point.Empty);
	}

	protected override void OnPaint(PaintEventArgs e)
	{
		bufferGraphics.DrawLine(new Pen(this.ForeColor),
			0, 0, this.Width, this.Height);
		e.Graphics.DrawImageUnscaled(buffer, Point.Empty);
	}

	protected override void OnSizeChanged(EventArgs e)
	{
		base.OnSizeChanged(e);
		this.ResetBuffer();
	}
}

Sorry dass das jetzt so viel ist - habe grad keine Zeit mein Copy&Paste auszusortieren... Aber die Propperties von mir brauchste nicht groß beachten...
Für dich dürfte CreateParams interessant sein.

Dabei noch eine Frage an die Experten (nur so aus interesse): Da das integrierte DoubleBuffering mit transparenz nicht mehr funktioniert musst ich mir das natürlich selber bauen. Habe mir daher das einfach mal aus den fingern gezogen, ohne mich groß zu informieren. Entspricht meine Vorgehensweise da so der Praxis???

Ich habe allerdings inzwischen aufgegeben:

aus der Beantwortung der Frage könnte man ja weitere Schlüsse ziehen. Insofern wäre eine Antwort schon spannend.

Also - ich habe mal das mit den Events probiert - ich denke der Ansatz würde theoretisch auch funktionieren. Der Aufwand dafür ist aber Unverhältnissmäßig zum Ergebniss.
Meine Idee, die Eventhandler aus dem transparenten Control anzumelden (nämlich über this.Parent.Controls..... etc.) scheint so ohne weiteres nicht zu gehen.

Ich habe daher folgenden Entschluss gefasst:
In der Zeit, in der ich es schaffen würde .Net 2.0 beizubringen, ein Control echt transparent darzustellen, und das mit einem stabilen Ergebniss, kann ich mich wohl 2x in WPF einarbeiten. Darüber habe ich gestern mal ein wenig gegooglet und in WPF scheinen solche Dinge wohl zum Alltagsgeschäft zu gehören. In sofern hat sich das Problem für mich wohl in wohlgefallen aufgelöst 😁

Dennoch besten Dank für eure Antworten 😉

09.09.2007 - 11:17 Uhr

Korrigier mich bitte jemand, wenn ich falsch liege - aber in WinForms gibt es doch eigentlich keine transparenten Controls, da man andere Controls nur in der eigenen OnPaint - Methode (oder entsprechend im Paint-Event) übermalen kann.
Oder verwechsle ich da jetzt etwas

Richtig - darum muss ich mir ja selber ein transparentes bauen und suche nach einer Lösung, damits gescheit klappt.
Aber du hast mich grad auf eine Idee gebracht - vieleicht sollt ich mich mal mit WPF auseinandersetzten - da wird sowas sicherlich kein großes Problem sein.

das wäre die spannende Frage.

Meinst du das nun ironisch nach dem Motto "selbstverständlich geht das (nicht)" oder findest du die Frage wirklich spannend? 😁
Wie auch immer - auf jeden Fall ist das ja eigentlich eh nicht dass was ich mir vorstelle.
Kann ich vieleicht irgendwie im Konstruktor meines transparenten Controls durch alle im Parent angemeldeten Controls gehen und dort jeweils eine Routine aus meiner Control-Klasse als entsprechendes Event anmelden? Dann könnte ich das Invalidate() aus der eigenen Klasse machen und müsste es nicht immer neu implementieren.

09.09.2007 - 10:35 Uhr

wie kannst du es regeln?

Naja, jedem Control dass sich mit meinem Transparenten Control überschneidet im OnFocus() (oder ähnliche Eventhandler, was genau es dann sein müsste weiß ich grad noch nicht) den überschneidenden Teil im transparenten Control ungültig machen. Habe es praktisch noch nicht ausprobiert, aber das müsste ja an sich gehen.
Aber wie schon gesagt - diese Vorgehensweise wär reichlich unefektiv. Insbesondere weil ich dann ja immer zur Entwicklungszeit diese ganzen Events implementieren muss. Bei vielen Controls, die sich wohlmöglich auch noch dynamisch platzieren (darauf wird es hinauslaufen) kein leichtes Unterfangen und sehr ineffizient denke ich.
Daher suche ich an dieser Stelle eine Möglichkeit, das ganze etwas eleganter (dynamischer, automatischer, wie auch immer 🙂 ) zu lösen??? Stehe leider immer noch auf'm Schlauch... ?(

09.09.2007 - 00:10 Uhr

Hehe, ich glaube du hast mein Problem nicht ganz verstanden.
Das Control IST im Vordergrund 😉

Darum habe ich die überlappungen in meinem Test-Form auch nicht komplett gemacht, damit ich mit Maus an die anderen, darunterliegenden Controls herankomme.

Wie gesagt, wenn ich mit der Maus über den freien Teil des Buttons fahre, oder in das Textfeld klicke, übermalen diese Controls mein transparentes Control.
Oder setzt das Framework die unten liegenden Controls zur Laufzeit von selbst in den Vordergrund, wenn sie aktiv werden??? 🤔
Das kann an sich nicht sein. Denn wenn ich das Fenster minimiere, und wieder hervorhole, ist alles wieder so wie's eigentlich sein soll.

Aber dennoch danke für den Tipp 😉

08.09.2007 - 23:37 Uhr

Hallo Leute

habe mir heute ein Transparentes Control gebaut. Funktioniert dank der vielen Threads die es dazu schon hier gab auch ganz gut.
Ich habe aber ein Problem, zu dem ich hier noch keine Antwort gefunden habe: Liegt ein Control hinter dem transparenten Control, und wird aktiviert, übermalt es den Bereich, wo eigentlich mein transparentes Control ist.
Hier der Vorher-/Nachhervergleich:

Wie mach ich es, dass sich mein Control automatisch neu zeichnet, wenn ein darunterliegendes Control den Fokus erhält?
Natürlich kann ich das im Container (hier das Form), der die entsprechenden Controls enthält, über die einzelnen EventHandler regeln. Ich würde das aber viel lieber automatisieren, da dieser Vorgang eh immer so passieren soll, und ich nicht jedes mal, wenn ich mein Formular verwenden will, die EventHandler anpassen möchte.
Der Vollständigkeit halber hier (zugegeben rudimementärer) Code vom Konstruktor und den beiden Paint-Methoden:


public ExtendedControl()
{
	InitializeComponent();
	this.backColor = Color.FromArgb(30, Color.Black);
	this.buffer = new Bitmap(this.Width, this.Height);
	this.bufferGraphics = Graphics.FromImage(this.buffer);
}
// ...
protected override void OnPaintBackground(PaintEventArgs e)
{
	bufferGraphics.FillRectangle(
		new SolidBrush(this.backColor),
		new Rectangle(Point.Empty, this.Size));
}

protected override void OnPaint(PaintEventArgs e)
{
	bufferGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
	bufferGraphics.DrawLine(
		new Pen(this.ForeColor),
		0, 0, this.Width, this.Height);
	bufferGraphics.DrawLine(
		new Pen(this.ForeColor),
		0, this.Height, this.Width, 0);
	e.Graphics.DrawImageUnscaled(this.buffer, Point.Empty);
}

10.12.2006 - 12:04 Uhr

Hat keiner eine Idee?
Selber habe ich das Problem leider noch nicht beheben können und die Weiten des Internets schweigen sich auch darüber aus...
Ich bin mir sicher das Problem liegt weniger an den Midi-Funktionen aus der API sondern daran, wie ich die Funktionen in C# eingebunden habe...

05.12.2006 - 18:43 Uhr

Jaja, so eine Verschachtelung ist schon mehr als Grenzwertig. Aber das Ergebniss spricht ja für sich 😉

05.12.2006 - 15:15 Uhr

Hab mich mal an den MSIL-Code davon gewagt.
Bin, was MSIL-Code angeht noch nich so versiert, daher könnten meine Schlüsse auch falsch sein =)

Jedenfalls wird im 2. fall das ganze direkt in die Konstante 36 optimiert und in IL gar nichts abgefragt.

Im ersten fall scheint es, als läd er zunächst die Konstante 18 (bedingt durch die erste Abfrage). Das + dahinter interpretiert er nicht als arithmetisches +, sondern als Concat. Er verbindet also 18 mit dem folgenden "a". Danach prüft er das Erbeniss - also das 18 + "a" (hab gerade keinen Plan was davon das Ergebnis sein müsste 🤔 ) mit "b" - auf Gleichheit. Die Abfrage wird sicherlich falsch sein - also lädt er wieder die Konstante 18. Da das + aber bereits abgearbeitet ist, passiert weiter nichts, außer das die 18 in x gespeichert wird.

Wie gesagt - könnte auch alles murks sein was ich hier schreibe. aber so würd ich das jetzt interpretieren (vieleicht kann mal ein MSIL-Experte was dazu sagen???)

05.12.2006 - 13:14 Uhr

Hallo C#-Community

steh mal wieder vor einem Problemchen.
Bin gerade dabei die Win32 API Funktionen für MIDI verwenden.
Die technische Seite funktioniert soweit auch ganz gut (öffnen von Devices etc.). Allerdings habe ich einen gravierenden "Schönheitsfehler", den ich beseitigen muss/will:
Mit der Funktion midiOutGetDevCaps bekomme ich nicht alle Infos in meine Struktur. Vor allem der Name bleibt leer (und auch der Typ ist immer 0).
Genug der Worte - hier ein wenig Code:
Das ist meine MIDIOUTCAPS Struktur.


internal struct MIDIOUTCAPS
    {
        public ushort       wMid;
        public ushort       wPid;
        public ushort       vDriverVersion;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string       szPname;
        public DeviceType   wTechnology;
        public ushort       wVoices;
        public ushort       wNotes;
        public ushort       wChannelMask;
        public uint         dwSupport;
    }

Die Einbindung der API-Funktion:


[DllImport("Winmm.dll")]
static extern MMRESULT midiOutGetDevCaps(
            uint wDeviceID,
            ref MIDIOUTCAPS lpCaps,
            uint wSize);

Und der Aufruf der Funktion:


this.Win32_MidiOutCaps = new MIDIOUTCAPS();
MMRESULT Result = midiOutGetDevCaps(
    this.DeviceID,
    ref this.Win32_MidiOutCaps,
    (uint)Marshal.SizeOf(Win32_MidiOutCaps));

Die Struktur wird auf jeden Fall schon gefüllt (die Manufacturer- und ProductID haben korrekte Werte) - nur eben nicht vollständig...

Thx for Help
Marauder

27.07.2006 - 08:27 Uhr

Erstmal danke dass hier die Antworten so schnell reinflattern 👍

Also mein Problem ist, dass ich, was das tiefergehende Arbeiten mit Controls angeht, noch ziemlicher noob bin (man muss ja zu seinen schwächen stehen ^^ ).
Ok, erst mal gut zu wissen, dass das mit dem zeichnen kein Problem ist. Aber wie setz ich denn da an?
Muss die RichTextBox Besitzer des zu zeichnenden Objekts sein und es im Paint-Event auffordern, sich zu zeichnen?
Oder muss ich die Graphics-Klasse der RichTextBox dem Object übergeben, damit es sich selbstständig in der RichTextBox darstellen kann?

26.07.2006 - 14:11 Uhr

Nun Gut, da hab ich wohl nicht richtig gesucht... vielen Dank für den Verweis. Das kommt der Sache eigentlich schon sehr nahe - allerdings will ich das mit den Akkorden etwas anders angehen:
Bei mir sind die Akkorde nicht einfacher Text, sondern Objekte, die sich selbstständig zeichen (zur Zeit zwar auch nicht mehr als einfacher Text, aber das soll bei zeiten kompexer werden, z. B. mit Griftabelle für Gitarre und solche Spielereien).
Das stellt mich halt vor das Problem, dass
1.) ...die RichEditBox in der Lage sein muss, ein fremdes Objekt auf sich zeichnen zu können.
2.) ...2 Zeilen nicht direkt untereinander erscheinen, sondern einen Abstand haben für die Akkorde (es sollten keine Leerzeilen sein).

25.07.2006 - 10:25 Uhr

Hallo allerseits

ich benötige eine angepasste RichEditBox, mit einigen besonderen Fähigkeiten.
Sie muss in der Lage sein, andere Objekte/Controls darstellen zu können
Da ich die Anforderungen nur schwer in Worte fassen kann, hier die Hintergründe und ein Beispiel:
Ich möchte ein Programm entwickeln, mit dem man Lead Sheets erstellen kann (die Musiker unter euch sollten wissen, worum es geht). Man hat also einen Text von einem Lied (das ist der eigentliche Text der EditBox) und darüber müssen die entsprechenden Akkorde erscheinen (Beispielsweise durch ein gesondertes Label oder eine Single-Line Editbox). Es muss auch möglich sein, die Position der Akkorde (bzw. fremden Objekte) an ein bestimmtes Zeichen der Editbox zu binden.
Hier nun das direkte Beispiel:

\***
C        F        am
Liedtext Liedtext Liedtext Liedtext 
am       C        em
Liedtext Liedtext Liedtext Liedtext 
\***

EDIT: Da ist die darstellung mal wieder HTML zum Opfer geworden - also eigentlich sollen die Akkorde immer jeweils über dem L stehen.

"C", "F", "am" & "em" sind hier die Objekte, die nicht als Text der RichEditBox dargestellt werden sollen, sondern extra Objekte repräsentieren.
Hier ist deren Position immer an das "L" gebunden.

Leider fehlt mir für die Umsetzung jeglicher Ansatz - hab schon hier gesucht und auch ge-google-t, aber bin nich fündig geworden.

Gruß
Julian