Abou Chleih

{the magic lies between the brackets}

Menü Schließen

Autor: Daniel Abou Chleih (Seite 1 von 4)

[C#] Transponieren einer Matrix

Eine Matrix wird transponiert indem man ihre Spalten gegen ihre Zeilen tauscht.
Eine Matrix A der Ordnung 3×2 wird somit eine Matrix ATrans mit der Ordnung 2×3

Die allgemeine Definition lautet:
Für die Matrix A

Quelle: Wikipedia

ist die transponierte Matrix AT definiert als

Quelle: Wikipedia

Somit ergäbe sich für folgende Matrix A mit der Ordnung 2 Zeilen x 3 Spalten

Matrix_A_2R3C_123_456

die folgende transponierte Matrix AT mit der Ordnung 3 Zeilen x 2 Spalten

Matrix_ATrans_3R2C_14_25_36

Die Umsetzung des Transponierens lässt sich in C# mit folgendem Code bewerkstelligen,

int m, n;
Console.Write("Ordnung der Matrix angeben: \r\n");
Console.Write("Zeilen: ");
m = Convert.ToInt16(Console.ReadLine());
Console.Write("Spalten: ");
n = Convert.ToInt16(Console.ReadLine());
int[,] A = new int[m, n];
int[,] Atrans = new int[n, m];

Console.Write("Elemente der Matrix eingeben: ");
for (int i = 0; i < m; i++)
{
	for (int j = 0; j < n; j++)
	{
		A[i, j] = Convert.ToInt16(Console.ReadLine());
	}
}

Console.WriteLine("\nMatrix A: ");
for (int i = 0; i < m; i++)
{
	for (int j = 0; j < n; j++)
	{
		Console.Write(A[i, j] + "\t");
		Atrans[j, i] = A[i, j];
	}
	Console.WriteLine();
}

Console.WriteLine("Transponierte (ATrans) Matrix : ");
for (int i = 0; i < n; i++)
{
	for (int j = 0; j < m; j++)
	{
		Console.Write(Atrans[i, j] + "\t");
	}
	Console.WriteLine();
}
Console.Read();

UML Beziehungen und ihre Umsetzung im Code

Wer Software plant und entwickelt wird unweigerlich mit der Unified Modeling Language (kurz UML) in Berührung kommen.
Ich werde in  diesem Blog-Eintrag vor allem auf das Klassendiagramm, genauer auf die Beziehungen der einzelnen Klassen eingehen.

Das Klassendiagramm:

UML_ClassdiagramDas Klassendiagramm zeigt  Klassen eines Namespaces an und deren jeweilige Abhängigkeiten. Es handelt sich um eine statische Darstellung, da lediglich die Attribute und Methoden, sowie die Verbindungen der Klassen untereinander dargestellt werden. Es wird nicht gezeigt, wie diese Verbindungen stattfinden.

Darstellungselemente:

Zur Realisierung eines Klassendiagramms stehen folgende Formen und Notationen zur Verfügung

Klasse

ClassEine Klasse wird mit als Rechteck dargestellt und enthält Attribute und Methoden (Operationen). Sollte es sich um eine abstrakte Klasse handeln, so wird der Klassennamen kursiv dargestellt

Zusätzlich werden die in der Klasse enthaltenen Attribute und Operationen (bspw. Methoden) mit deren Daten- oder ggf. Rückgabetypen und Sichtbarkeiten dargestellt.

Class_ExplanationClass_AttrOperation

Zur Darstellung der Sichtbarkeit von Attributen und Funktionen bietet UML folgende Zeichen:

  • + steht für public, also eine öffentliche Funktion/ein öffentliches Attribut
  • # steht für protected, also eine geschützte Funktion/ein geschütztes Attribut
  • – steht für eine private Funktion/ein privates Attribut

Wie Anfangs erwähnt, stellt das Klassendiagramm auch die Beziehungen der Klassen untereinander dar. Ich werde in diesem Beitrag auf folgende Beziehungen eingehen und zu der jeweiligen Beziehung ein Codebeispiel (C#) geben:

  • Vererbung
  • Binäre Assoziation (zwei Klassen sind beteiligt)
  • Aggregation
  • Komposition
Vererbung:

Eine Vererbung (engl.: Inheritance) ist auch als „Ist-Ein-Beziehung“ oder „Ist-Implementiert-Als-Beziehung“ bekannt.

Als Beispiel dienen hier die Klassen Employee und Manager
Da ein Manager auch ein Mitarbeiter (Employee) ist, erbt die Klasse Manager von Employee
Dadurch werden Variablen, Felder und Methoden, welche nicht private sind in die erbende Klasse übernommen.
Achtung: Konstruktoren werden nicht vererbt und müssen daher manuell angesprochen werden:

public Manager(string _name):base(_name){ ... }

Die Umsetzung in C# würde wie folgt aussehen (Bild):

[spoiler title=“Employee-Klasse“ style=“fancy“ anchor=“BeispielVererbung“]

namespace Vererbung
{
    class Employee
    {
        static int staticID = 1;

        protected int ID = 0;
        protected string Name = "";

        public Employee(string _name)
        {
            CreateEmployee(_name);
        }

        protected void CreateEmployee(string _name)
        {
            staticID++;
            ID = staticID;
            Name = _name;
        }

        public int getID()
        {
            return ID;
        }

        public string getName()
        {
            return Name;
        }
    }
}

[/spoiler]

[spoiler title=“Manager-Klasse“ style=“fancy“]

namespace Vererbung
{
    class Manager:Employee
    {
        static int staticManagerID = 1;

        int ManagerID;

        public Manager(string _name):base(_name)
        {
            CreateManager();
        }

        private void CreateManager()
        {
            staticManagerID++;
            ManagerID = staticManagerID;
        }

        public int getManagerID()
        {
            return ManagerID;
        }
    }
}

[/spoiler]

(Binäre) assoziation:

Eine Assoziation ist eine beliebige Beziehung zwischen den Objekten von Klassen. Hier werden wir nur die binären Assoziationen (2 Klassen sind beteiligt) behandeln.

Dies ist eine gerichtete Assoziation, das bedeutet, dass Klasse 1 die Klasse 2 kennt, dagegen Klasse 2 nichts von Klasse 1 weiß. In der Beschreibung wird Beschrieben auf welche Weise die Objekte in Verbindung stehen

Links sehen wir eine bidirektionale binäre Assoziation, d.h. die Firma kennt seinen Mitarbeiter und der Mitarbeiter seine Firma.

Die Form der Assoziation sähe in der Programmierung wie folgt aus (Man beachte die Kommentierung):

[spoiler title=“Bidirektionale binäre Assoziation“ style=“fancy“ anchor=“BeispielAssoziation“]

public class Firma 
{ 
  public Mitarbeiter mitarbeiter; 
}

 public class Mitarbeiter 
{ 
  public Firma firma; 
}

public class Verzeichnis
{ 
  Mitarbeiter Mustermann = new Mitarbeiter(); 
  Firma  Musterfirma  = new Firma(); 
  Mustermann.firma  = Musterfirma;
  Musterfirma.mitarbeiter = Mustermann; 
  // Man beachte, dass die Objekte von Firma und Mitarbeiter in einer
  // weitern Klasse liegen und somit nicht voneinander abhängig sind
  // und somit weiterleben, auch wenn eines der Objekte zerstört wird
}

[/spoiler]

Aggregation:

Bei der Aggregation handelt es sich um eine spezielle Form der Assoziation. Sie ist auch als „Ganzes-Teil-Beziehung“ oder „Hat-Ein-Beziehung“ bekannt.
Darunter versteht man ein Objekt (Aggregatobjekt), welches aus verschiedenen Einzelteilen (Objekten) besteht, wobei diese nicht existenzabhängig sind (d.h. sie leben weiter, auch wenn das Aggregatobjekt zerstört wird.

Eine Beispiel für eine Aggregation wäre das Auto (als Ganzes) und ein Rad, als Teil.

[tabs]
[tab title=“Allgmeines Beispiel“]

public class Aggregatklasse
{
    ExistenzUnabhängigeKlasse objKlasse;
    public void doSomething(ExistenzUnabhängigeKlasse obj)
    {
      //Das Objekt der Klasse ExistenzUnabhängigeKlasse wird als Parameter übergeben 
      objKlasse = obj; 
	  // und ist somit noch existent wenn die Aggregatklasse zerstört wird
    }
}

[/tab]
[tab title=“Auto-Rad-Beispiel“]Wird nachgereicht…

[/tab]
[/tabs]

Komposition:

CompositionBei der Komposition handelt es sich um eine strenge Form der Aggregation. Das Kompositionsobjekt besteht, wie bei der Aggregation auch, aus mehreren Einzelteilen (Komponentenobjekte), welche jedoch im Gegensatz zur Aggregation mit der Zerstörung des Ganzen (Kompositionsobjekt) zerstört werden (Existenzabhängigkeit).
Damit ist auch die Kardinalität/Multiplizität auf Seite des Kompositionsobjekts immer 1. Das bedeutet, dass eine Komponente nur Teil eines Objekts sein kann. Somit wird sichergestellt, dass die Lebensdauer aller Objekte gleich ist. Die Kardinalität auf der Seite der Komponenten kann jedoch variable sein

Beispiel:
Ein Kunde einer Bank hat mindestens eine Anschrift und keine oder mehrere hinterlegte Bankverbindungen (kann per Rechnung zahlen).

CompositionExampleStirbt der Kunden, so wohnt er logischerweise nicht mehr und ist ebenso wenig ein Kunde der Bank. Seine Anschrift(en), sowie seine Bankverbindung(en) werden also zerstört

Die Umsetzung im Code würde wie folgt aussehen:

[spoiler title=“Codebeispiel Komposition“ style=“fancy“ anchor=“BeispielKomposition“]

public class CompositionClass
{
    SomeUtilityClass objSC = new SomeUtilityClass(); //Das Objekt der Klasse
    // existiert lediglich in der CompositionClass und wird mit dem Objekt der
    // CompositionClass vernichtet

    public void doSomething()
    {
        objSC.someMethod();
    }
}

[/spoiler]

Die ersten Wochen im nebenberuflichen Studium an der FOM

Bereits nach meinem Abitur habe ich mich mit dem Thema Studium beschäftigt, wollte zu diesem Zeitpunkt jedoch kein Studium beginnen, da ich erst einmal ein wenig flüssig werden wollte und zudem auch (ich bin ehrlich) keine Lust auf noch mehr „Schule“ hatte.

Also entschied ich mich für eine Ausbildung als Fachinformatiker, was im Nachhinein betrachtet auch die richtige Entscheidung war. Ich konnte während meiner Ausbildung einige Erfahrung im ERP-Umfeld (Dynamics NAV) sammeln und erhielt auch erste Einblicke in den wirklichen Ablauf eines Unternehmens.

Schon während meiner Ausbildung festigte sich mein Entschluss, dass ich nach meiner Ausbildung studieren möchte und so machte ich mir erste Gedanken zu diesem Thema.
Ich zuerst mit dem Gedanken ein Vollzeitstudium zu absolvieren und als Minijobber weiterhin beim ACE beschäftigt zu bleiben oder mich für ein Fernstudium einzuschreiben (wobei ich diese Alternative nicht favorisierte)

Da ich jedoch als Ersatz für einen in altersbedingt (Rente) ausscheidenden Kollegen ausgebildet wurde, war mein Ausbilder von dieser Idee nicht begeistert und schlug mir ein nebenberufliches Studium an der FOM in Stuttgart vor.

Die Webseite machte einen guten Eindruck, das ZEIT-Ranking der Hochschule war gut und auch die Erfahrungsberichte machte einen guten Eindruck. So besuchten mein Ausbilder und ich einen Info-Abend an der FOM und waren überzeugt.

So schrieb ich mich an der FOM für das Wintersemester 2014 im Fach Wirtschaftsinformatik (B.Sc.) ein und am 5. September 2014 startete offiziell das Semester (nach der Eröffnungsveranstaltung am 03.09.13) mit der ersten Vorlesung.

Im ersten Semester haben wir übrigens folgende Studienfächer:

  • Management Basics
  • E-Business
  • Prozedurale Programmierung
  • IT-Basics

WIESO WIRTSCHAFTSINFORMATIK?

Während meiner Ausbildung wurden immer wieder Änderungen am unserem ERP-System vorgenommen – Viele davon im Bereich der Buchhaltung. Programmiertechnisch verstand ich die Änderungen, jedoch fehlte mir an vielen Stellen der betriebswirtschaftliche Hintergrund. Somit wollte ich dieses Wissen erweitern ohne mich jedoch komplett von der Informatik zu entfernen.

Die Wirtschaftsinformatik war somit der perfekte Zwischenweg um dies zu bewerkstelligen

ABLAUF des studiums

Bei dem Studium an der FOM handelt es sich um ein Präsenzstudium. Vor Beginn des Semesters wurden die Skripte über das Onlineportal (Online Campus) verteilt. Diese sollte man ausdrucken und während der Vorlesung bereithalten, sodass man sich ggf. auf einer Seite Notizen machen kann

Die Benotung der einzelnen Fächer erfolgt durch s.g. Scientific Abstracts und einer Klausur. Bei dem Scientific Abstract handelt es sich um eine kurze prägnante Zusammenfassung (max. 2 Seiten) zu einem bestimmten Thema. Während des Semesters werden 4-5 Themen genannt, zu denen man sich vorbereiten sollte (Hausarbeit). Zu einem genannten Termin wird dann eines dieser Themen gewählt und es wird unter Prüfungsbedingungen eine Zusammenfassung zu dem Thema geschrieben.

Diese wird mit 20% gewichtet. Zudem schreibt man Klausur, welche mit 80% gewichtet wird

DIe erste vorlesung

Unsere erste Vorlesung war im Fach Management Basics. Hier wurden uns bisher vor allem betriebswirtschaftliche Grundlagen vermittelt (bspw. Unternehmensformen, SWOT-Analyse, Target Costing…), auf welche in späteren Modulen aufgebaut wird.

Zu Beginn nahm ich zu den Vorlesungen im Fach Management Basics mein Tablet mit Tastatur und das Skript in digitaler Form mit. In dem PDF habe ich dann digitale Notizen hinzugefügt.

Mittlerweile habe ich das Skript jedoch gedruckt, denn es ist wesentlich schneller und einfacher die Notizen handschriftlich auf das Skript zu schreiben.

Man sollte sich auch nicht der Illusion hingeben, dass es so wie bisher in der Schule läuft. Der Prof wird euch nicht sagen, was ihr aufschreiben sollt und was nicht. Ihr müsst selbst die wichtigen Dinge selbst filtern und zu Papier bringen.

Windows Phone 8.1 – Neuerungen im Überblick

Wie bereits vielen bekannt, befindet sich Windows Phone 8.1 in der finalen Phase und wird voraussichtlich am 14.April für die Hersteller und Entwickler freigegeben.

Hier ein kleiner  Überblick über die Neuerungen:
1. Statusleiste
2. Cortana (Pendant zu Siri)
3. VPN
4. Internet Explorer 11 (mit Button zum Tabwechsel und Sync)
5. Storage Sense (Speicherverbrauchsanzeige)
6. Getrennte Lautstärke für Medien und Signale (Anrufe etc.)
7. App2SD (Apps auf Speicherkarte installieren)

Kleinere Neuerungen:
1. Man kann nun Apps auch mit einem Wisch nach unten beenden
2. Der Kalender hat nun auch eine Wochenansicht
3. Es gibt nun s.g. Ruhezeiten, also Zeiten in denen das Handy nicht schellt
4. Die Kamera-App wurde überarbeitet.
5. Mehr Tiles im Hauptmenü (6 Spalten)

[OTRS] Internet Explorer 10 – Keine Umbrüche möglich/Einfügen nicht möglich

In der OTRS Version 3.1.1 ist es mit dem Internet Explorer 10 nicht möglich Zeilenumbrüche per Enter-Taste im Textfeld einzufügen.
Wechselt man in den Dokumentenmodus des Internet Explorers 9 oder niedriger, so ist es wieder möglich Zeilenumbrüche einzufügen.

Um den Dokumentenmodus des IE9 zu erzwingen, muss man zwei Dateien des OTRS anpassen.

Beide Dateien befinden sich unter

C:\OTRS\OTRS\Kernel\Output\HTML\Standard

1. Datei: CustomerHeader.dtl

Hier muss Head der Datei die Zeile

<meta http-equiv=“X-UA-Compatible“ content=“IE=edge,chrome=1″ />

zu

<meta http-equiv=“X-UA-Compatible“ content=“IE=EmulateIE9,chrome=1″ />

geändert werden.

2. Datei: HTMLHead.dtl

In der HTMLHead.dtl-Datei muss die selbe Änderung vorgenommen werden.

Edge bedeutet dass der Internet Explorer den Dokumentenmodus mit der höchsten Version verwenden soll. EmulateIE9 erzwingt den Dokumentenmodus des Internet Explorers 9

[OTRS] Weitere Abteilung anbinden

Ich werde hier erklären, wie man vorgehen kann, falls eine weitere Abteilung das Ticketsystem nutzen möchte , jedoch  eigene Queues besitzen und nur Zugriff auf die Tickets in dieser Queue haben soll.

Vorgehensweise:

Nachdem ein Agent/mehrere Agenten für die Abteilung angelegt wurde(n), muss man Gruppen erzeugen.

Diese werden über die Administration und dem Menü Gruppen erstellt

OTRS_Admin_Gruppen

2014-02-10 13_53_33

2014-02-10 13_54_01

Zu diesen Gruppen fügen wir die Agenten hinzu.
Beispiel: Agent: „NeueGruppeAgent“ wird zur Gruppe „NeueGruppe“ hinzugefügt

2014-02-10 13_56_57

Entweder man definiert die Gruppen gleich nachdem man den Agenten erstellt hat oder später über das Menü Agent <-> Gruppen

Hier binden wir den Agenten an die jeweilige Gruppe

2014-02-10 13_57_25

Nun müssen wir die Queues erstellen und der Gruppe zuordnen. Dies kann man bei der Einrichtung einer Queue einstellen, ebenso kann man im gleichen Zug die E-Mail Adresse, welche Benachrichtigungen verschickt konfigurieren. Diese Mailadresse kann im Adminmenü unter E-Mail-Einstellungen -> E-Mail Adressen konfiguriert werden.

2014-02-10 14_13_31

Nachdem die Queues angelegt wurden, kann man noch die Benachrichtigungen anpassen.
Dazu einfach die Einstellungen der alten Benachrichtigungen übernehmen und die Queues, sowie den Text der neuen Benachrichtigung anpassen.

Damit wären wir soweit fertig. Nun kann man noch die Sichbarkeiten der Reiter anpassen, damit die Abteilung keinen Zugriff auf etwaige Addons oder die (Kunden)-Konfiguration hat

Reiter:

[divider]

Damit die Abteilung nicht alle Reiter besitzt, muss man 1. sicherstellen, dass sie nicht den zu den Reitern gehörigen Gruppen zugeordnet sind (bspw. Reiter FAQ <=> Gruppe: faq, faq-admin, faq-approval) und 2. kann man in der SysConfig für jeden Reiter Sichtbarkeiten für Gruppen definieren.

Dies geht für viele Reiter in deren ModuleRegistration.
Beispiel Reiter Kunden:
Konfigurationseinstellungen bearbeiten in Framework -> Frontend::Admin::ModuleRegistration

 Frontend::Module###AdminCustomerUser

dort die Gruppen hinzufügen, welche den Reiter sehen sollen.

[OTRS] Queue in Übersicht ausblenden, Zugriff erhalten

Manchmal kann es vorkommen, dass man eine Queue im OTRS nicht in der Übersicht eingeblendet haben möchte, den Zugriff darauf aber benötigt (bspw. um immer wieder einen Überblick zu erhalten).
Um dies zu erreichen, kann man in den Einstellungen unter
Frontend::Agent::Ticket::ViewQueue
den Eintrag ViewAllPossibleTickets auf Ja setzen
2014-01-28 10_11_18-Ticket -_ Frontend__Agent__Ticket__ViewQueue - SysConfig - Admin - ACE Service P
Somit werden auch die Queues, auf welche man nur ‚ro‘-Berechtigung in der Queue Ansicht nach Queues angezeigt. Jetzt kann man für die Agenten die ‚rw‘-Berechtigung für die Gruppe , welche Berechtigung auf die Queue hat entfernen und damit die Queue aus der Übersicht entfernen.

[C#/.NET] Eigenen OpenFileDialog erstellen

Zwar hat das .NET-Framework mit den von der CommonDialog-Klassen ebernden Dialog-Klassen (dazu gehören OpenFileDialog, FolderBrowserDialog) schon Dialoge, welche die Funktion bieten Daten zu öffnen, zu speichern oder das Verzeichnis zu wählen. Diese sind aber leider nicht erweiterbar und daher nicht für sämtliche Zwecke zu gebrauchen.

In diesem Beitrag werde ich deshalb eine Möglichkeit aufzeigen, einen eigenen Dialog zu erstellen für verschiedene Zwecke zu erstellen.

Einfacher Dialog zum Öffnen von Dateien

Zum Erstellen eines einfachen OpenFileDialogs benötigen wir erstmal eine Form. In der Form platzieren wir ein TreeView, sowie zwei Buttons. Zusätzlich benötigen wir eine ImageList, welche die eigentlichen Icons der Dateien und Verzeichnisse zwischenspeichert und aus welcher wir die benötigten Icons beziehen werden.

Nachdem wir die benötigten Controls hinzugefügt haben, benötigen wir eine Methode, die uns alle Laufwerke in die TreeView lädt. Diese bilden nämlich jeweils den Stammknotenpunkt (RootTreeNode).

Die Methode sieht wir folgt aus und soll bei dem Aufruf der Form durchlaufen werden:

private void GetAllDrives()
{
	DriveInfo[] drives = DriveInfo.GetDrives();
	foreach (var drive in drives)
	{
		TreeNode rootTreeNode = new TreeNode();
		rootTreeNode.Text = drive.Name;
		rootTreeNode.Tag = drive.Name;
		rootTreeNode.ImageIndex = GetIconOfFile_Folder(drive.Name);
		rootTreeNode.SelectedImageIndex = rootTreeNode.ImageIndex;
		rootTreeNode.Nodes.Add(" "); //Placeholder to enable expanding (+)
		FolderAndFiles_treeView.Nodes.Add(rootTreeNode);
	}
}

Die Methode GetIconOfFile_Folder bezieht das Icon des Elements, wie es der Windows Explorer auch anzeigt.
Zum Beziehen wird der Namespace System.Runtime.InteropServices benötigt. Diesen binden wir per

using System.Runtime.InteropServices;

ein.
Folgender Code wird zum Beziehen der Icons benötigt:

[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
	public IntPtr hIcon;
	public IntPtr iIcon;
	public uint dwAttributes;
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
	public string szDisplayName;
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
	public string szTypeName;
};

class Win32
{
	public const uint SHGFI_ICON = 0x100;
	public const uint SHGFI_LARGEICON = 0x0;    // 'Large icon
	public const uint SHGFI_SMALLICON = 0x1;    // 'Small icon

	[DllImport("shell32.dll")]
	public static extern IntPtr SHGetFileInfo(string pszPath,
								uint dwFileAttributes,
								ref SHFILEINFO psfi,
								uint cbSizeFileInfo,
								uint uFlags);
}

private int GetIconOfFile_Folder(string Path)
{
	IntPtr hImgSmall;    //the handle to the system image list
	SHFILEINFO shinfo = new SHFILEINFO();

	hImgSmall = Win32.SHGetFileInfo(Path, 0, ref shinfo,
								   (uint)Marshal.SizeOf(shinfo),
									Win32.SHGFI_ICON |
									Win32.SHGFI_SMALLICON);

	System.Drawing.Icon myIcon =
		   System.Drawing.Icon.FromHandle(shinfo.hIcon);

	FolderAndFiles_imageList.Images.Add(myIcon);

	return FolderAndFiles_imageList.Images.Count - 1; //Ab 0 (zero) wird angefangen, somit ist die Gesamtzahl n+1
}

Bisher werden nur die aufklappbaren Laufwerke angezeigt. Sie besitzen jedoch noch keine weiteren Knoten. Diese füllen wir indem wir einen EventHandler für das BeforeExpand-Event mittels

FolderAndFiles_treeView.BeforeExpand += FolderAndFiles_treeView_BeforeExpand;

erstellen.

Die dazugehörige Methode FolderAndFiles_treeView_BeforeExpand sieht wie folgt aus:

private void FolderAndFiles_treeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
	e.Node.Nodes.Clear();
	GetFilesAndFolder(e.Node, (string)e.Node.Tag);
}

Das Event ruft also die Methode GetFilesAndFolder auf, welche zuerst die unter dem erweiterten Knoten liegenden Knoten löscht und danach die Verzeichnisse und Dateien bezieht. Diese Methode benötigt zum einen den erweiterten Knoten, sowie das Verzeichnis aus welchem die Ordner und Dateien bezogen werden sollen (dies wurde im Tag gespeichert) als Parameter.
Die Methode selbst sieht wie folgt aus:

private void GetFilesAndFolder(TreeNode tn, string Path)
{
	try
	{
		string[] Directories = Directory.GetDirectories(Path);
		string[] Files = Directory.GetFiles(Path);

		foreach (string dir in Directories)
		{
			TreeNode dirTreeNode = new TreeNode();
			dirTreeNode.Tag = dir;
			dirTreeNode.Text = new DirectoryInfo(dir).Name;
			dirTreeNode.ImageIndex = GetIconOfFile_Folder(dir);
			dirTreeNode.SelectedImageIndex = dirTreeNode.ImageIndex;
			dirTreeNode.Nodes.Add(" ");
			tn.Nodes.Add(dirTreeNode);
		}

		foreach (string file in Files)
		{
			TreeNode fileTreeNode = new TreeNode();
			fileTreeNode.Tag = file;
			fileTreeNode.Text = new FileInfo(file).Name;
			fileTreeNode.ImageIndex = GetIconOfFile_Folder(file);
			fileTreeNode.SelectedImageIndex = fileTreeNode.ImageIndex;
			tn.Nodes.Add(fileTreeNode);
		}
	}
	catch (Exception ex)
	{
		MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
	}
}

Den schwierigsten Teil haben wir jetzt hinter uns, die Dateien und Verzeichnisse werden bezogen und in der TreeView angezeigt und die jeweiligen Icons bezogen.
Jetzt müssen wir lediglich noch die zwei Buttons belegen.
Ich habe dies so gelöst:
Abbrechen

private void Cancel_button_Click(object sender, EventArgs e)
{
	this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
	this.Close();
}

Annehmen

private void Accept_button_Click(object sender, EventArgs e)
{
	string filePath = (string)FolderAndFiles_treeView.SelectedNode.Tag;
	if (CheckIfPathIsFile(filePath) == true) // Sollte es sich um eine Datei handeln
	{
		this.FilePath = filePath; //Bei FilePath handelt es sich um ein public Property
		this.DialogResult = System.Windows.Forms.DialogResult.OK;
		this.Close();
	}
	else //Sollte es sich um ein Verzeichnis handeln
	{
		FolderAndFiles_treeView.SelectedNode.Expand(); //erweitere den aktuell gewählten Knoten
	}
}

In der Methode des AcceptButton-ClickEvents wird auch geprüft, ob es sich bei dem gewählten Element um eine Datei oder ein Verzeichnis handelt. Dies geschieht mit folgender Methode:

private bool CheckIfPathIsFile(string Path)
{
	FileAttributes attr = File.GetAttributes(Path);
	if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
		return false;
	else
		return true;
}

Es wird also Wahr zurückgegeben, wenn es sich um eine Datei handelt.

Zu guter Letzt müssen wir nur noch den FileDialog aufrufen, dies geschieht mit folgender Methode:

private void OpenSimpleFileDialog()
{
	SimpleOpenFileDialog simpleOpenFileDia = new SimpleOpenFileDialog();
	if(simpleOpenFileDia.ShowDialog() == System.Windows.Forms.DialogResult.OK)
		MessageBox.Show(simpleOpenFileDia.FilePath);
}

Das Ergebnis sieht wie folgt aus:

2013-12-02 14_43_34-SimpleOpenFileDialog

[WP8] PDF-Datei aus dem Web laden und per App anzeigen

Eine PDF-Datei aus dem Web herunterzuladen und anzuzeigen ist relativ einfach.
Folgender Methoden laden die Webseite, laden die PDF-Datei herunter, speichern diese in den Isolated Storage und starten die externe App mit dem Pfad der Datei.

Folgende Links geben weitere Informationen zu folgendem Code:

WebClient pdfDownloader = null;
string LastFileName = ""; //Speichert den Dateinamen der zuletzt gesicherten Datei

private void StartPDFDownload()
{
    pdfDownloader = new WebClient(); //prevents that the OpenReadCompleted-Event is called multiple times
    pdfDownloader.OpenReadCompleted += DownloadPDF; //Create an event handler
    pdfDownloader.OpenReadAsync(new Uri("Your URL as string with HTTP://")); //Start to read the website
}

async void DownloadPDF(object sender, OpenReadCompletedEventArgs e)
{
    byte[] buffer = new byte[e.Result.Length]; //Gets the byte length of the pdf file
    await e.Result.ReadAsync(buffer, 0, buffer.Length); //Waits until the rad is completed (Async doesn't block the GUI Thread)

    using (IsolatedStorageFile ISFile = IsolatedStorageFile.GetUserStoreForApplication())
    {
        try
        {
            LastFileName = "tempPDF" + DateTime.Now.Ticks + ".pdf";
            using (IsolatedStorageFileStream ISFileStream = ISFile.CreateFile(LastFileName))
            {
                await ISFileStream.WriteAsync(buffer, 0, buffer.Length);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message + Environment.NewLine + ex.HResult,
                ex.Source, MessageBoxButton.OK);
            //Catch errors regarding the creation of file
        }
    }
    OpenPDFFile();
}

private async void OpenPDFFile()
{
    StorageFolder ISFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
    try
    {
        IStorageFile ISFile = await ISFolder.GetFileAsync(LastFileName);
        await Windows.System.Launcher.LaunchFileAsync(ISFile);
            //http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206987%28v=vs.105%29.aspx
    }
    catch (Exception ex)
    {
        //Catch unknown errors while getting the file
        //or opening the app to display it
    }
}

[2009 R2 RTC] Reiter(ActionGroup) Abteilungen ausblenden

Mit dem Role-Tailored-Client hat sich in Dynamics NAV einiges verändert. So wurden rollenbasierte Menüs eingeführt, welche individuell für jede Rolle gestaltet werden können.
Standardmäßig ist jedem Menü auch der Reiter Abteilungen hinzugefügt. Hinter diesem verbergen sich sämtliche Pages aller Abteilungen, somit hat der Benutzer auch die Möglichkeit diese aufzurufen.

Dynamics NAV bietet aber die Möglichkeit den Reiter für bestimmte Rollen zu entfernen. In folgendem werde ich beschreiben, wie man den Reiter ausblendet.

Wir rufen den RTC-Client im Configuration-Mode auf. Dazu öffnen wir die Verknüpfung und fügen im Ziel den Parameter

-configure

sowie das Profil, in welchem der Reiter ausgeblendet werden soll (hier BUCHHALTER/IN TEST)

-profile:“BUCHHALTER/IN TEST“

an.

Das sollte das ungefährt so aussehen:

2013-10-25 11_32_10

Sollte nun beim Starten von Navision folgende Fehlmeldung auftauchen:

2013-10-25 11_34_03

So müsst ihr Rollenbasierter Client -> Profile dem gewählten Profil eine Besitzer-ID hinzufügen.
2013-10-25 11_37_12

Nachdem das erledigt ist, könnt ihr den RTC im Configuration-Mode starten und den Navigationsbereich anpassen:
2013-10-25 11_41_48

In Navigationsbereichs-Designer könnt ihr nun den Reiter „Abteilungen“ entfernen

2013-10-25 11_42_44

ACHTUNG: Ihr könnt den Reiter Abteilungen nicht einfach wieder hinzufügen! Dies ist nur möglich, indem man die Standardeinstellungen wiederherstellt. Dadurch gehen aber sämtliche sonstigen Änderungen ebenfalls verloren!

Nachdem ihr den Reiter gelöscht habt und mit OK bestätigt habt, müsst ihr lediglich euren Client neustarten.

© 2018 Abou Chleih. Alle Rechte vorbehalten.

Thema von Anders Norén.