Laden...

Forenbeiträge von Alf Ator Ingesamt 764 Beiträge

28.08.2015 - 10:44 Uhr

Was du machen kannst, ist im Quellcodeverwaltungs-Explorer mit Rechtsklick auf das jeweilige Projekt -> Erweitert -> Verdecken

Warum die Projekte beim Anlegen eines neuen Arbeitsbereiches direkt gezogen werden, kann ich dir leider nicht erklären.

27.08.2015 - 17:59 Uhr

Hallo 23994,

möglicherweise hast du ein Häkchen in
Optionen
-> Quellcodeverwalung
-> Umngebung
-> 'Alle abrufen,...'

Gruß, Alf

24.08.2015 - 09:28 Uhr

Hallo mpeter,

ohne auf dein Problem jetzt konkret einzugehen, empfehle ich dir die Lecktüre von [Artikelserie] SQL: Parameter von Befehlen

Gruß, Alf

17.07.2015 - 17:36 Uhr

das die SW durch Überarchitektur 3 mal so lange braucht, und der Wartungsaufwand dadurch verdoppelt wird

Ich habe es bisher nur anders herum erlebt. Das heißt: quasi keine Architektur -> hoher Wartungsaufwand. Ich kenne es auch nur so, dass die BWLer möglichst schnelle eine billige Lösung haben wollen und das Architektur nicht interessiert.

03.07.2015 - 10:05 Uhr

Hallo m.grauber,

wir benutzen in meinem Betrieb Interop, zur Fernsteuerung von Office, wollen es aber nach und nach abschaffen, da es fehleranfällig und langsam ist.

Ich habe mich nun für das Late Binding entschieden, da ich nicht schon wieder ein Fremdtool nutzen möchte.

Ich habe mir NetOffice angeschaut und war recht angetan. Imho spricht nichts dagegen das zu verwenden. Würden wir nicht von Interop wegkommen wollen, hätte ich NetOffice als Grundlage für die Fernsteuerung eingeführt. Ich bin kein Freund davon, das Rad ständig neu zu erfinden.

  • Wenn die eigene C# Anwendung als 32bit kompiliert wird, sollte Office 32 Bit unterstützt werden, wenn sie 64bit kompiliert wird, sollte auch das Office 64 Bit unterstützt werden. Alles am besten in einem einzigen Code. Der Kunde setzt dann je nach dem entweder die 32 Bit oder die 64 Bit Version ein.
    -> Ich habe gerade auf dem Entwicklungsrechner nur ein Office32-Bit installiert. Ich müsste demnach die Methoden noch für 64 Bit anpassen?

Schau dir mal an, was NetOffice in der FAQ dazu sagt. Imho ist das Problem dort auch schon gelöst.

  • Mit einer anderen Entwicklungsumgebung hatte ich bei der Automation Probleme (allerdings erst ab Office 2010;

Office bzw Interop.Office versucht ja immer abwärtskompatibel zu sein und muss dafür intern immer mehr Krücken verwenden. Irgendwann geht das halt nicht mehr. Office2013 verhält sich anders als Office2010. Deswegen haben wir bei uns alle Office-Versionen älter als Office2013 abgeschafft.

alle Office-Vorversionen funktionieren einwandfrei), wenn ich das Word-Dokument per Automation geöffnet habe, es vom Benutzer bearbeitet wurde und ich die Verbindung zum Word bis zum Schließen gehalten habe, um nach dem Schließen von Word wieder in mein Programm zurück zu gelangen und weiteren Code abzuarbeiten. Sporadisch riss dort manchmal die Verbindung ab obwohl das Dokument noch offen war – wahrscheinlich weil Word irgendwelche Ressourcen aufgeräumt hat. Habt Ihr solche Probleme ebenfalls – evtl. auch erst nach längerer Zeit oder einem Rechner Standby?

Das tritt auch aber Version 2013 auf. Hier ein Link dazu:
http://blogs.artinsoft.net/Mrojas/archive/2012/09/28/Office-Interop-and-Call-was-rejected-by-callee.aspx

Gruß, Alf

21.05.2015 - 16:41 Uhr

Ein ViewModell KANN wie eine Entität aussehen; aber das ist ganz ganz ganz ganz selten der Fall.

Leider nicht ganz soo selten X( X( X(

05.05.2015 - 11:29 Uhr

Hallo _Cashisclay,

Vielleicht hilft dir [FAQ] Warum blockiert mein GUI? weiter.

Viele Grüße, Alf

30.04.2015 - 16:54 Uhr

Ich habe zu dem Thema auch noch ein paar interessante Links gefunden. Ich muss mich anscheinend über gewisse Dinge noch einlesen. Wenn ich durch bin, werde ich meine entsprechende Lösung hier posten. Danke für die Anregungen und Hilfe.

Fragen Entity Framework, Repository Pattern und Schichtentrennung
Lebensdauer Entity Framework (Context)
Using Repository and Unit of Work patterns with Entity Framework 4.0
Developer's Guide to Dependency Injection Using Unity
Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC Application (9 of 10)

30.04.2015 - 11:59 Uhr

Ich versteh das alles nicht. ?( ?( 8o 🤔 X(

Bestimmte Repositories müssen doch den gleichen DbContext verwenden.
Diese Abhängigkeiten sollen aber nur im DAL bekannt sein.
Der Service im BL bekommt also Repositories injected, kennt die Abhängigkeiten aber nicht.

Die Abhängigkeiten müssen aber irgendwo gehalten werden, richtig?

Also habe ich eine statische DatabaseInstance erstellt, die die UnitOfWorks hält und über die die Repositories geholt werden können.


public class CategoryService
{
    public CategoryRepository Categories { get; private set; }

    public CategoryService(CategoryRepository categories)
    {
        this.Categories = categories;
    }

    public void Commit()
    {
        this.Categories.Save();
    }
}

public static class ServiceFactory
{
    public static CategoryService CreateCategoryService(ILoginCredentials loginCredentials)
    {
        return new CategoryService(DatabaseInstance.GetCategoryRepository(loginCredentials)); ;
    }
}

public static class DatabaseInstance
{
    private static CategoryUnitOfWork _categoryUnitOfWork;

    public static CategoryRepository GetCategoryRepository(ILoginCredentials loginCredentials)
    {
        if (_categoryUnitOfWork == null)
            _categoryUnitOfWork = UnitOfWorkFactory.CreateCategoryUnitOfWork(loginCredentials);

        return _categoryUnitOfWork.Categories;
    }
}

30.04.2015 - 10:52 Uhr

...
Und sauber testbar ist das ganze auch nicht. Repositories sollte man in die Services via Dependency Injection übergeben
...

Ich habe das nochmal angeschaut und mittels FactoryPattern gelöst:


public static class UnitOfWorkFactory
{
    public static CategoryUnitOfWork CreateCategoryUnitOfWork(ILoginCredentials loginCredentials)
    {
        var context = new ToolContext(loginCredentials);
        var categoryUnitOfWork = new CategoryUnitOfWork();
        categoryUnitOfWork.SetCategoryRepository(RepositoryFactory.CreateCategoryRepository(context));
        categoryUnitOfWork.SetUsageRepository(RepositoryFactory.CreateRepository<Usage>(context));
        categoryUnitOfWork.SetTaskTypeRepository(RepositoryFactory.CreateRepository<TaskType>(context));
        return categoryUnitOfWork;
    }
}


public class CategoryService
{
    private readonly CategoryUnitOfWork _unitOfWork;
        
    public CategoryService(ILoginCredentials loginCredentials)
    {
        _unitOfWork = UnitOfWorkFactory.CreateCategoryUnitOfWork(loginCredentials);
    }

    public void Commit()
    {
        _unitOfWork.Categories.Save();
        _unitOfWork.Usages.Save();
        _unitOfWork.TaskTypes.Save();
    }
}

30.04.2015 - 10:36 Uhr

Hallo Abt,

Dein Service ist dein Unit Of Work oder was soll das heissen? 👶
...
und der Service sollte vom Context gar nichts wissen.
Das wäre eine Schichtverletzung in meinen Augen.

Um dich richtig zu verstehen:
Services sind bei dir im BL angesiedelt? Dort sollte vom Context nichts zu sehen sein.


public class CategoryService
{
    private readonly CategoryUnitOfWork _unitOfWork;
        
    public CategoryService(ILoginCredentials loginCredentials)
    {
        _unitOfWork = new CategoryUnitOfWork(loginCredentials);
    }
}

Das UnitOfWork ist im DAL angesiedelt und mein CategoryService ist in Wirklichkeit ein UoW und ich nenne es deswegen auch mal so:


    public class CategoryUnitOfWork : IUnitOfWork
    {
        private readonly ToolContext _context;

        public RepositoryBase<Category> Categories { get; private set; }
        public RepositoryBase<Usage> Usages { get; private set; }
        public RepositoryBase<TaskType> TaskTypes { get; private set; }

        public CategoryUnitOfWork(ILoginCredentials loginCredentials)
        {
            _context = new ToolContext(loginCredentials);

            this.Categories = new RepositoryBase<Category>(this._context);
            this.Usages = new RepositoryBase<Usage>(this._context);
            this.TaskTypes = new RepositoryBase<TaskType>(this._context);
        }
    }

...
Und sauber testbar ist das ganze auch nicht. Repositories sollte man in die Services via Dependency Injection übergeben
...

Das verstehe ich jetzt nicht ganz: Um die Repositories zu erstellen muss ich doch den Context haben und der ist nur im UoW bekannt.

Das ist _eigentlich _der Inhalt eines Repositories; nicht eines Services.
Spezifisch erweiterbar sind Deine Repositories so übrigens nicht.

Also besser so:


public class CategoryRepository : RepositoryBase<Category>
{
    public CategoryRepository(ToolContext context) : base(context) { }

    public IQueryable<Category> GetCategoriesByUsageName(string usageName)
    {
        return this.FindBy(categoryItem => categoryItem.Usages.Any(usageItem => usageItem.Name == usageName));
    }
}

Ich glaube mein Thema hat nichts mehr mit dem Ursprünglichen zu tun. Vielleicht sollte man das in einen eigenen Thread verschieben.

29.04.2015 - 12:25 Uhr

Hallo Mossi,

so könnte eine entsprechende UnitOfWork aussehen.
Für den Scope existiert **ein ** Context. Andere UnitsOfWork sollten sich mit diesem nicht in die Quere kommen.
Pro Table ein Repository.


public class CategoryService // = UnitOfWork
{
	private readonly Context _context;

	public RepositoryBase<Category> Categories { get; private set; }
	public RepositoryBase<Usage> Usages { get; private set; }
	public RepositoryBase<TaskType> TaskTypes { get; private set; }

	public CategoryService(string server, string user, string password)
	{
		this._context = new ToolContext(server, user, password);
		this.Categories = new RepositoryBase<Category>(this._context);
		this.Usages = new RepositoryBase<Usage>(this._context);
		this.TaskTypes = new RepositoryBase<TaskType>(this._context);
	}
}

So ein das Repository-Interface mit den standardmässigen ACID-Methoden:


public interface IGenericRepository<TEntity> where TEntity : class
{
    IQueryable<TEntity> GetAll();
    TEntity GetSingle(int id);
    IQueryable<TEntity> FindBy(Expression<Func<TEntity, bool>> predicate);
    void Add(TEntity entity);
    void Delete(TEntity entity);
    void Edit(TEntity entity);
    void Save();
}

Erweitertes Informations-Bedürfnis könnte auch im UnitOfWork befriedigt werden:


public class CategoryService // = UnitOfWork
{
    ....

    public IQueryable<Category> GetCategoriesByUserId(int userId)
    {
        return this.Categories.FindBy(categoryItem => categoryItem.id_user == userId);
    }
}

Gruß, Alf

08.04.2015 - 17:35 Uhr

Hallo VIERcntHOLZ,

Bei VB gibts ja:

AddHandler event, AddressOf eventhandler

Das ist die C#-Variante in grün. So wie sie Th69 angegeben hat.
Der EventHandler für WindowsForms-Controls wird meistens in der entsprechenden Designer-Datei zu finden sein.

Schöne Grüße, Alf

20.03.2015 - 09:31 Uhr

Hallo basstscho,

ich hatte mich mal mit dem Thema beschäftigt und folgende Lösung verwendet:

Distinguishing Barcode Scanners from the Keyboard in WinForms

Using Raw Input from C# to handle multiple keyboards

Hat funktioniert, ist allerdings nicht sehr einfach umzusetzten.

Gruß, Alf

11.03.2015 - 10:18 Uhr

Hallo ErfinderDesRades,

ich hatte mich tatsächlich an dein Projekt drangesetzt und hatte dabei festgestellt, dass die 3-Schichten-Architektur erst dann Sinn macht, wenn man das Projekt entsprechend erweitert wird.

Das habe ich jetzt nicht weiterverfolgt, werde das in den nächsten Tagen aber mal umsetzten.

Imho ein prima Beispiel, wie einem so eine Anwendung über den Kopf wachsen und durch 3-Schichten-Architektur wieder übersichtlich gemacht werden kann.

Gruß, Alf

02.03.2015 - 12:48 Uhr

Hallo,

ich habe das jetzt folgendermaßen gelöst:


static void Main(string[] args)
{
    string hexString = "45 72 73 74 65 72 21 20 56 69 65 6c 65 6e 20 44 " +
                        "61 6e 6b 20 66 fc 72 20 64 69 65 20 48 69 6c 66 " +
                        "65 20 75 6e 64 20 6c 69 65 62 65 20 47 72 fc df " +
                        "65 20 61 6e 20 64 61 73 20 46 6f 72 75 6d 2e ";
    string convertedHexString = ConvertHexStringToString(hexString);

    Console.WriteLine(convertedHexString);
    Console.ReadLine();
}

private static string ConvertHexStringToString(string hexString)
{
    string result = "";

    foreach (string hexPart in hexString.Trim().Split(' '))
    {
        result += ConvertHexPartToString(hexPart);
    }

    return result;
}

private static string ConvertHexPartToString(string hexPart)
{
    int value = Convert.ToInt32(hexPart, 16);
    return Char.ConvertFromUtf32(value);
}

Der Ergebnisstring ist übrigens folgender:

Erster! Vielen Dank für die Hilfe und liebe Grüße an das Forum.

27.02.2015 - 09:56 Uhr

Hallo liebe Forenteilnehmer,

ich versuche einen Hex-String in einen lesbaren String umzuwandeln.
Ich habe dafür die Funktion Convert.ToString versucht. Es werden aber
immer noch nur die Hex-Werte angezeigt.

Wie kann ich das denn Konvertieren?


string hexString = "45 72 73 74 65 72 21 20 56 69 65 6c 65 6e 20 44 61 6e 6b 20 66 fc 72 20 64 69 65 20 48 69 6c 66 65 20 75 6e 64 20 6c 69 65 62 65 20 47 72 fc df 65 20 61 6e 20 64 61 73 20 46 6f 72 75 6d 2e";
string result = Convert.ToString(hexString);
Console.WriteLine(result);

Viele Grüße, Alf

27.02.2015 - 09:16 Uhr

Danke für deinen Einsatz, herbivore!

30.01.2015 - 09:57 Uhr

Hallo Exis,

Hier der Link von oben nochmal in deutsch: https://msdn.microsoft.com/de-de/magazine/dd419663.aspx

Es ist eigendlich alles schon gesagt worden. Wenn du mal ein komplexeres Projekt hast, erklärt sich MVVM quasi von selbst.
Bei so kleinen Projekten kann man MVVM auch mal MVVM sein lassen. Genau das, was deine Frage aufgeworfen hat.

Gruß, Alf

27.01.2015 - 09:42 Uhr

Ich bin kein Fan von Spielen aber auch begeistert von Deinem Elan.
Lass Dich also nicht davon beeinflussen, dass wenig Leute antworten - ich bin auch nur der stille Leser 😉

Dito! 👍

23.01.2015 - 13:00 Uhr

Hallo Rioma,

wenn du das Model direkt in der View bindest, dann musst du wohl einen 'unschönen' Weg gehen, der View aus dem Model heraus das Update mitzuteilen.

Möglicherweise könntest du auch das Binding aktualisieren, wenn du ein Object in List<Model2> einfügst. Auch nicht wirklich schön. 😛

Beste Grüße, Alf

21.03.2014 - 07:25 Uhr

Danke schön für eure Antworten. Mir kamen schon echte Zweifel, ob ich mit meinem Kram nicht total auf dem Holzweg bin. Der andere Entwickler hat immerhin schon über 20 Jahre Berufserfahrung.
Ich bin in der Situation ruhig geblieben und habe versucht zu begründen, warum ich das so uns so gemacht habe.
Ein Beispiel: Ich habe eine modular zusammensetzbare GUI entwickelt. Geschäftslogik und Module werden in unterschiedlichen Projekten organisiert. Er ist der Meinung, dass das unnötiger Overhead ist, wenig bringt und nur zusätzliche Arbeit macht. Ich habe das so gemacht, um die Wartbarkeit und Übersichtlichkeit meines Projektes zu erhöhen. Wenn man offen drüber nachdenkt, hat das was er sagt auch seine Berechtigung. Vielleicht muss man da einen Mittelweg finden.

@herbivore
Richtig, ich wechsel den Arbeitgeber. Die alte Firma ist klein und liegt mir wegen Chef und Kollegen auch am Herzen. Es ist mir also leider nicht egal, wie es da weiter geht.

@Coder007
Durch seine Haltung spricht er mir ja die Kompetenz ab. Ich werde in darauf hinweisen, dass das so nicht in Ordnung ist.

Mit meinen Projekten muss er weiterarbeiten. Vielleicht kann ich ihm meine Entwickler-Welt dann etwas näher bringen.

Vielen Dank nochmal für die Antworten. Schöne Grüße, Alf

20.03.2014 - 20:41 Uhr

Hallo Zusammen!

Wegen Arbeitgeberwechsel, übergebe ich meine Projekte an einen Kollegen.
Das Problem: Ich habe immer versucht meine Projekte nach aktuellem Erkenntnisstand zu entwickeln. Dass heisst, ich versuche mich nach Designpatterns wie MVVM und Vorgaben nach Clean Code Developers zu richten. Der o.g. Entwickler ist negativ gegenüber Microsoft und C#.NET eingestellt. Projektstrukturen und andere Sachen, die ich entworfen habe, findet er wortwörtlich Pisskacke. Er enwickelt mit Embarcadero C++.

Wie soll man in so einer Situation denn bitte reagieren?

Viele Grüße, Alf

10.11.2013 - 14:17 Uhr

Hallo STF-DIR,

die Methode, die du suchst heisst String.PadRight.

Gruß, Alf

Edit:
Was natürlich auch etwas ausmacht, ist die Schriftart. Verwende am einfachsten eine Schrifart, mit gleicher Länge pro Zeichen. Das nennt sich Monospace oder so.

28.10.2013 - 09:49 Uhr

Klare Ansage. Das gibt mir jetzt zu denken, da ich für ein größeres Projekt mit vielen Datensätzen (10 Mio+) das Entity Framework einsetzten will.

28.10.2013 - 09:43 Uhr

Hast du Massendaten zu verarbeiten, ist weder DataSet noch ORMapper sinnvoll, sondern nur die DB Sprache ( SQL/NoSQL).

Das irritiert mich jetzt ein wenig. Sind moderne ORMapper wirklich so schlecht?

21.10.2013 - 14:25 Uhr

Hallo NaCoder,

such doch mal im Forum nach "pfad der exe". Herbivore hat ein schönes FAQ dazu geschrieben.

18.09.2013 - 20:07 Uhr

(Mein Programm ist auf 162875 Ergebnisse gekommen (Quersumme 29) ... X

18.09.2013 - 08:29 Uhr

8o Ich habe gestern noch ein kleines Progrämmchen geschrieben, dass mir das ausrechnet und das läuft immer noch. Ist wohl ein bisschen langsam. Schöne Aufgabe.

10.09.2013 - 11:13 Uhr

Hallo Ralf,

das im XmlSerializer ein bug ist (zumindest so einer) halte ich erst mal für unwahrscheinlich. Der wird soviel benutzt, das wäre doch schon aufgefallen. Da es nur sporadisch auftritt, könnte ich mir vorstellen, dass ein threading-problem vorliegt. Möglicherweise versucht er gleichzeitig zwei mal in die Xml-Datei zu serialisieren.

Gruß, Alf

05.09.2013 - 16:37 Uhr

Hallo Theo,

zu 2. noch ein kleine Idee, du könntest bei Bereichsüberschreitung den Text rot anzeigen, dann weiss der User bescheid, dass etwas nicht stimmt, kann aber trotzdem ungehemmt schreiben.

Gruß, Alf

02.09.2013 - 09:17 Uhr

Hallo med, es gibt Programme (z.B. Winserv), mit denen man andere Programme als Dienst ausführen lassen kann. Möglicherweise funktioniert das auch bei dir. Probier das doch mal aus.

Gruß, Alf

31.08.2013 - 09:10 Uhr

Was ist, wenn ein Folder keine Files enthält?

24.08.2013 - 11:49 Uhr

Welche Antwort bekommt denn das Original? Und was sendet das Original darauf hin? Das müsste mit Wireshark ja auch ersichtlich werden. Ein praktisches Tool zum Netzwerk-Verkehr tracen ist auch: TcpTrace

25.07.2013 - 16:28 Uhr

Hallo AyrA,

erstmal danke. Durch dein Projekt, habe ich mich mal mit esoterischen Programmiersprachen beschäftigt und mit deinem Programm sogar ein Hello World in Befunge geschrieben.
War etwas schwierig, weil Stop und ein paar weiter Optionen noch nicht ganz funktionieren.

Schönen Gruß, Alf

25.07.2013 - 16:11 Uhr

Hallo falsecode,

probiers mal mit StringSplitOptions.RemoveEmptyEntries.

die Variable 'Path' solltest du besser klein schreiben. Es gibt nämlich schon eine Klasse Path im System.IO-Namespace.

Gruß, Alf

24.07.2013 - 11:18 Uhr

Hallo Mary81,

es hilft auch, das Neuzeichnen des DGV, während des Ladens, zu verhindern. Ich weiss jetzt leider nicht aus dem Kopf, wie das geht.

Gruß, Alf

17.07.2013 - 14:28 Uhr

Hallo lot2learn,

ohne mich jetzt mit der Thematik gut auszukennen ein paar Vorschläge:

Was passiert, wenn du das Fenster für den Zeitraum der Berechnung minimierst, unsichtbar machst, oder hinter einem anderen Fenster versteckst.

So wie ich dass sehe, willst du Daten verändern. Gibt es in der Anwendung die Möglichkeit, die Daten abzuspeichern und wieder zu laden?

Viele Grüße, Alf

17.07.2013 - 14:18 Uhr

hallo falsecode,

dein Problem ist ein Paradebeispiel für 'Waurm blockiert meine GUI'.
Ein Backgroundworker, der die Festplatte durchsucht, ist genau der richtige Weg um Sachen gleichzeitig zu machen. Nämlich das Fortschrittsfenster auf dem laufenden zu halten, ohne es zu blockieren und die Daten zu laden.

Viele Grüße, Alf

04.07.2013 - 18:51 Uhr

Ich habe xUnit verwendet und kann nichts Negatives darüber sagen. Allerdings ist es das einzige Testing-Framework, dass ich bisher verwendet habe und ich habe wenig Erfahrung damit.

04.04.2013 - 17:05 Uhr

Hallo lot2learn,

ist es denn notwendig, dass die Ausgabe in einem Consolen-Fenster erfolgt?
Ansonsten könnstest du auch mit einer Kombination aus z.b. log4net oder NLog und TraceEye - Professional LogViewer oder Tail4Win arbeiten.
Also die Ausgabe in Log-Dateien schreiben und die Anzeige mit einem anderen Programm erfolgen lassen.

Gruß, Alf

25.03.2013 - 09:35 Uhr

Hallo Scavanger,

danke für die schöne Lösung. (Ich konnte erst jetzt antworten, weil ich krank im Bett lag.)

Also, du bist jetzt dran.

Gruß, Alf

15.03.2013 - 17:06 Uhr

Ok, danke!

Ich hab mir das was überlegt:
Ihr sollt die Methode GetShortestWay für die Klasse Link implementieren.


class Link
{
    public int ID { get; set; }
    public List<Link> Links { get; set; }

    public Link(int id)
    {
        this.ID = id;
        this.Links = new List<Link>();
    }

    public string GetShortestWay(int startID, int goalID)
    {
        // Viel Spaß!
            
        // [ ... ]

        return "0 -> 7 -> 3 -> 15 -> 4";
    }

    private void Add(Link link)
    {
        if(!this.Links.Contains(link))
            this.Links.Add(link);
    }

    private Link GetRandomLink(Random random)
    {
        int index = random.Next(0, this.Links.Count + 1);
        if (index >= this.Links.Count)
            return this;
        else
            return this.Links[index].GetRandomLink(random);
    }

    public static Link CreateRootLink(int maxLinkCount, int randomLinksCount)
    {
        Link rootLink = new Link(0);
        Random random = new Random(DateTime.Now.Millisecond);
        for (int i = 1; i < maxLinkCount; i++)
            rootLink.GetRandomLink(random).Add(new Link(i));
        for (int i = 1; i < randomLinksCount; i++)
            rootLink.GetRandomLink(random).Add(rootLink.GetRandomLink(random));
        return rootLink;
    }

    public override string ToString()
    {
        return String.Format("{0}: {1} ({2})", this.ID, this.Links.Count,String.Join(", ", this.Links.Select(link => link.ID)));
    }
}

14.03.2013 - 16:54 Uhr

Hallo StefanG,

ich kenne mich mit dem WPF-Kram nicht so aus, aber ich vermute mal, dass Locator in einem anderen Namespace liegt. Den musst du erst bekannt machen.


<Window x:Class="..."
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:NamespaceVonLocator"
        .... >

Und dann noch:


<src:Locator x:Key="locator" />

Das src kann wohl frei gewählt werden.

Gruß, Alf

08.03.2013 - 13:03 Uhr

Ist aber ne ganze Menge geworden..

Ich hoffe, dass stört nicht, dass die 'Pixel' in der Console nicht quatratisch sind. Das kann man erreichen, in dem eine Verknüpfung an die kompilierte Exe erstellt und die Schriftgröße auf z.B. 8x8 einstellt. Andere Möglichkeit ist über die WinAPI. Ich finde aber, dass der Code schon umfangreich genug ist.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;

namespace RombusTest
{
    class Program
    {
        static void Main(string[] args)
        {
            CubeToRombusMorpher morpher = new CubeToRombusMorpher();
            morpher.Morph(3, 3, 60, 100);

            Console.ReadLine();
        }
    }
    
    public class CubeToRombusMorpher
    {
        private Timer timer;
        private List<Oktaeder> oktaeders;
        private IEnumerator<Oktaeder> enumerator;

        private class Point
        {
            public int X { get; set; }
            public int Y { get; set; }

            public Point(int x, int y)
            {
                X = x;
                Y = y;
            }
            public override string ToString()
            {
                return String.Format("({0}/{1})", X, Y);
            }
        }

        private class Oktaeder
        {
            public Point P1 { get; set; }
            public Point P2 { get; set; }
            public Point P3 { get; set; }
            public Point P4 { get; set; }
            public Point P5 { get; set; }
            public Point P6 { get; set; }
            public Point P7 { get; set; }
            public Point P8 { get; set; }

            public Oktaeder(int mx1, int my1, int mx2, int my2, int mx3, int my3, int mx4, int my4, int mx5, int my5, int mx6, int my6, int mx7, int my7, int mx8, int my8)
            {
                P1 = new Point(mx1, my1);
                P2 = new Point(mx2, my2);
                P3 = new Point(mx3, my3);
                P4 = new Point(mx4, my4);
                P5 = new Point(mx5, my5);
                P6 = new Point(mx6, my6);
                P7 = new Point(mx7, my7);
                P8 = new Point(mx8, my8);
            }

            public override string ToString()
            {
                return String.Join(", ", P1, P2, P3, P4, P5, P6, P7, P8);
            }
        }

        public void Morph(int x1, int y1, int length, int interval)
        {
            InitConsole(x1, y1, length);
            InitTimer(interval);
            InitOktaeders(x1, y1, length);
            DrawCube(x1, y1, x1 + length, y1 + length, ConsoleColor.Green);
            Console.ReadLine();
            timer.Start();
        }

        private void InitConsole(int x1, int y1, int length)
        {
            Console.SetWindowSize((x1 * 2) + length, (y1 * 2) + length);
            Console.SetBufferSize((x1 * 2) + length, (y1 * 2) + length);
        }

        private void InitOktaeders(int x1, int y1, int length)
        {
            oktaeders = new List<Oktaeder>();
            for (int i = 0; i <= (length / 2); i++)
            {
                int mx1 = x1,               my1 = y1 + i;
                int mx2 = x1 + i,           my2 = y1;
                int mx3 = x1 + length - i,  my3 = y1;
                int mx4 = x1 + length,      my4 = y1 + i;
                int mx5 = x1 + length,      my5 = y1 + length - i;
                int mx6 = x1 + length - i,  my6 = y1 + length;
                int mx7 = x1 + i,           my7 = y1 + length;
                int mx8 = x1,               my8 = y1 + length - i;
                oktaeders.Add(new Oktaeder(mx1, my1, mx2, my2, mx3, my3, mx4, my4, mx5, my5, mx6, my6, mx7, my7, mx8, my8));
            }
            enumerator = oktaeders.GetEnumerator();
        }

        private void InitTimer(int interval)
        {
            timer = new Timer();
            timer.Interval = interval;
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        }

        private void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            timer.Stop();
            Console.Clear();

            if (enumerator.MoveNext())
            {
                DrawOktaeder(enumerator.Current, ConsoleColor.Magenta);
                Console.WriteLine();
                Console.WriteLine(enumerator.Current);
            }
            else
            {
                oktaeders.Reverse();
                enumerator = oktaeders.GetEnumerator();
                if (enumerator.MoveNext())
                {
                    DrawOktaeder(enumerator.Current, ConsoleColor.Magenta);
                    Console.WriteLine();
                    Console.WriteLine(enumerator.Current);
                }
            }
            
            timer.Start();
        }

        private void DrawOktaeder(Oktaeder oktaeder, ConsoleColor color)
        {
            DrawLine(oktaeder.P1.X, oktaeder.P1.Y, oktaeder.P2.X, oktaeder.P2.Y, color);
            DrawLine(oktaeder.P2.X, oktaeder.P2.Y, oktaeder.P3.X, oktaeder.P3.Y, color);
            DrawLine(oktaeder.P3.X, oktaeder.P3.Y, oktaeder.P4.X, oktaeder.P4.Y, color);
            DrawLine(oktaeder.P4.X, oktaeder.P4.Y, oktaeder.P5.X, oktaeder.P5.Y, color);
            DrawLine(oktaeder.P5.X, oktaeder.P5.Y, oktaeder.P6.X, oktaeder.P6.Y, color);
            DrawLine(oktaeder.P6.X, oktaeder.P6.Y, oktaeder.P7.X, oktaeder.P7.Y, color);
            DrawLine(oktaeder.P7.X, oktaeder.P7.Y, oktaeder.P8.X, oktaeder.P8.Y, color);
            DrawLine(oktaeder.P8.X, oktaeder.P8.Y, oktaeder.P1.X, oktaeder.P1.Y, color);
        }

        private void DrawRombus(int x1, int y1, int x2, int y2, ConsoleColor color)
        {
            DrawLine(x1, (y1 + y2) / 2, (x1 + x2) / 2, y1, color);
            DrawLine((x1 + x2) / 2, y1, x2, (y1 + y2) / 2, color);
            DrawLine(x1, (y1 + y2) / 2, (x1 + x2) / 2, y2, color);
            DrawLine((x1 + x2) / 2, y2, x2, (y1 + y2) / 2, color);
        }

        private void DrawCube(int x1, int y1, int x2, int y2, ConsoleColor color)
        {
            DrawLine(x1, y1, x2, y1, color);
            DrawLine(x1, y1, x1, y2, color);
            DrawLine(x1, y2, x2, y2, color);
            DrawLine(x2, y1, x2, y2, color);
        }

        private void DrawLine(Point p1, Point p2, ConsoleColor color)
        {
            DrawLine(p1.X, p1.Y, p2.X, p2.Y, color);
        }
        private void DrawLine(int x1, int y1, int x2, int y2, ConsoleColor color)
        {
            ConsoleColor BackgroundColorTemp = Console.BackgroundColor;
            int cursorLeftTemp = Console.CursorLeft;
            int cursorTopTemp = Console.CursorTop;

            Console.BackgroundColor = color;

            int dx = Math.Abs(x2 - x1), sx = x2 < x1 ? -1 : 1;
            int dy = -Math.Abs(y2 - y1), sy = y2 < y1 ? -1 : 1;
            int err = dx + dy, e2;

            while (true)
            {
                Console.CursorLeft = x1;
                Console.CursorTop = y1;
                Console.Write(" ");
                if (x1 == x2 && y1 == y2) break;
                e2 = 2 * err;
                if (e2 > dy) { err += dy; x1 += sx; }
                if (e2 < dx) { err += dx; y1 += sy; }
            }

            Console.BackgroundColor = BackgroundColorTemp;
            Console.CursorLeft = cursorLeftTemp;
            Console.CursorTop = cursorTopTemp;
        }
    }
}

Edit: Da macht man noch ne winzige Änderung und hat gleich mal nen Fehler rein.. korrigiert.

20.02.2013 - 15:13 Uhr

Hallo leusl,

wie sehen denn eure konkreten Ansätze aus. Und wo genau liegen da eure Probleme?

Gruß, Alf

18.02.2013 - 14:07 Uhr

Hallo Timba,

habe neulich erst so ein Raspberry in der hand gehalten. Schönes Ding. 👍

Ich denke mal, die Entwicklung für den kleinen Computer hängt davon ab, was für ein Betriebssystem verwendet werden soll und welche Geräte angeschlossen werden. Bei der google-Suche nach 'raspberry pi visual studio' bin ich unter andem auf Developing a Raspberry PI app with Visual Studio gestoßen.

Gruß, Alf

Edit: Ich sehe grade, dass es mit der Express-Edition wohl nicht so einfach funktionieren wird, da:
"Visual Studio Express editions don't support add-ins and won't work with VisualGDB!"

Aber prinzipiell scheint es schonmal zu gehen.

Ne andere Möglichkeit die mir noch einfällt, wäre es, eine Linux-Distribution zu installieren und mit Mono zu entwickeln.

01.02.2013 - 08:28 Uhr

Hallo Hannobal,

möglicherweise ist Quartz.NET etwas für dich.

Gruß, Alf

30.01.2013 - 16:02 Uhr

Hallo mondwicht,

ich weiß leider auch nicht woran genau das jetzt liegt. Mein Vorschlag, wäre jetzt, dass du als nächstes dein Program gemäß [Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden stückweise verkleinerst, bis du etwa die Größe von meinem TestProjekt erreicht hast.

Dann sollte sich auch dieser vertrackte Fehler finden lassen, oder? 🤔

Gruß, Alf

30.01.2013 - 13:57 Uhr

Hallo mondwicht,

ich hab mal ein kleines TestProjekt gebaut:


DataSet dataSet = new DataSet();
dataSet.ReadXml(@"C:\TestData\dsTest.xml");
DataRow dataRow = dataSet.Tables[0].NewRow();
dataRow[0] = "test4";
dataSet.Tables[0].Rows.InsertAt(dataRow, 1);
dataSet.WriteXml(@"C:\TestData\dsTest2.xml");


<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<string>test1</string>
	<string>test2</string>
	<string>test3</string>
</Test>


<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <string>test1</string>
  <string>test4</string>
  <string>test2</string>
  <string>test3</string>
</Test>