Archiv der Kategorie: C#

.NET Winforms C# : Eine Baum-Komponente befüllen (TreeView)

Problem

Der TreeView-Baum soll anhand von Strings befüllt werden

Ansatz

Verwendung eines Backslashes wie bei Dateipfaden zur Baumeinrückung

Lösung

private void populateTreeFromStringArray(string[] lines)
{
	SortedList sl = new SortedList();
	this.treeView1.Nodes.Clear();
	this.treeView1.BeginUpdate();
	// this.treeView1.ShowRootLines;
	TreeNodeCollection parentNodes = this.treeView1.Nodes;
	foreach (string line in lines)
	{
		string[] stringParts = line.Split('\\');

		TreeNode nd = null;
		// Der Parent Key wird leer inititalisiert
		string strParentKey = string.Empty;
		foreach (string s in stringParts)
		{

			string sTrimmed = s.Trim();

			if (sTrimmed == string.Empty)
			{
				continue;
			}

			if (strParentKey.Length > 0)
			{
				strParentKey = string.Concat(strParentKey, @"\", sTrimmed);
			}
			else
			{
				strParentKey = string.Concat(strParentKey, sTrimmed);
			}

			if (sl.ContainsKey(strParentKey))
			{
				//verwende diesen
				nd = sl[strParentKey] as TreeNode;
			}
			else
			{
				//create new
				nd = new TreeNode(sTrimmed);
				//den FullPath adden
				sl.Add(strParentKey, nd);
				parentNodes.Add(nd);
			}

			parentNodes = nd.Nodes;
		}
	}
	this.treeView1.EndUpdate();
}

private void button4_Click(object sender, EventArgs e)
{
	 string[] lines=new string[]
	 {
		 @"E:\",
		 @"E:\Bier",
		 @"D:\Eigene Dateien",
		 @"D:\Programme\Games",
		 @"D:\Eigene Dateien\Eigene Musik2",
		 @"D:\",
		 @"D:\Eigene Dateien\Eigene Downloads\Multi",
		 @"D:\Eigene Dateien\Eigene Downloads\Multi\CD 1",
		 @"D:\Eigene Dateien\Eigene Downloads\Multi\CD 2",
		 @"D:\Eigene Dateien\Eigene Downloads\Multi\CD 3",
		 @"D:\Eigene Dateien\Eigene Downloads\Multi\CD 3\Teil 2",
		 @"D:\Eigene Dateien\Eigene Downloads\Multi\CD 4"
	 };

	 populateTreeFromStringArray(lines);
 }

ASP.NET / Sparx Systems Enterprise Architect : Read binary Image from Database ( BLOB ) and show / display it on a webpage

Problem

A binary picture that has been saved in a database or an Access File (i.e. of the Sparx Systems Enterprise Architect) shall be displayed on a web page.

Approach

  1. Create a new ASP.NET Webform and name it GetImage.aspx
  2. Go to the Page_Load function in it
  3. Paste the code under solution in the area in customize according your data structure (here it is Sparx EA).
  4. Create a img-Tag in HTML, that has a src-Attribute pointing to that webpage with a get parameter img={your image id}
  5. Use Response.BinaryWrite in the way shown below

Solution

using System;
using System.Collections.Generic;
using System.Data.OleDb;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class GetImage : System.Web.UI.Page
{
    // Mit folgender URL Kann ein Bild nun rausgeladen werden 
    // http://localhost:51241/GetImage.aspx?img=343868582
    // und entsprechend in HTML über den Image-Tag geladen werden:
    // <img src="GetImage.aspx?img=343868582" />
    protected void Page_Load(object sender, EventArgs e)
    {
        string sqlStatement = @"
            SELECT Image 
            FROM t_image 
            WHERE ImageID={ImageID}         
        ";

        sqlStatement = sqlStatement.Replace("{ImageID}", Request.QueryString["img"].Trim());

        OleDbConnection conn = new OleDbConnection(MyConfigurationManager.eapFilePath);

        try
        {
            conn.Open();
            OleDbCommand comm = new OleDbCommand();
            comm.Connection = conn;
            comm.CommandText = sqlStatement;

            OleDbDataReader reader = comm.ExecuteReader();

            while (reader.Read())
            {
                Response.ContentType = "image/jpeg"; // if your image is a jpeg of course
                Response.BinaryWrite((byte[])reader.GetValue(0));
            }
        }
        catch (Exception ex)
        {
            //return e.Message;
        }
        finally
        {
            conn.Close();
        }
    }
}

C#.NET + MS SQL Server : Nach INSERT direkt die Auto-Increment ID erhalten ohne zweite Abfrage

Problem

Um die Auto-Increment ID zu erhalten werden desöfteren 2 Statements abgesetzt, obwohl das INSERT-Statement direkt die Auto-Increment ID zurückgeben kann

Ansatz – Approach

Anstelle von comm.ExecuteNonQuery() sollte man lieber comm.ExecuteScalar() mit SELECT SCOPE_IDENTITY() kombinieren.

Lösung – Solution

public string insertMainTherapyData(string serial_no
                    ,string therapy_start
                    ,string machine_type
                    ,string file_source
                    ,string dialog_version
                    ,string tlc_version
                    ,string versions
                    ,DateTime uploaded_on
                    ,string uploaded_by
                    ,bool processed
                    ,string user_original_file
                    ,string user_country
                    ,string user_comment
                    ,string user_upload_reason
                    ,string user_location)
{
    string sqlStatement=@"
        INSERT INTO [dbo].[therapy]
                    ([serial_no]
                    ,[therapy_start]
                    ,[machine_type]
                    ,[file_source]
                    ,[dialog_version]
                    ,[tlc_version]
                    ,[versions]
                    ,[uploaded_on]
                    ,[uploaded_by]
                    ,[processed]
                    ,[user_original_file]
                    ,[user_country]
                    ,[user_comment]
                    ,[user_upload_reason]
                    ,[user_location])
        VALUES
                    (@serial_no
                    ,@therapy_start
                    ,@machine_type
                    ,@file_source
                    ,@dialog_version
                    ,@tlc_version
                    ,@versions
                    ,@uploaded_on
                    ,@uploaded_by
                    ,@processed
                    ,@user_original_file
                    ,@user_country
                    ,@user_comment
                    ,@user_upload_reason
                    ,@user_location);
            SELECT SCOPE_IDENTITY()
            ";
    int myID = -1;
    SqlConnection conn = new SqlConnection(MyConfigurationManager.prdSqlServerString);
    try
    {
        conn.Open();
        SqlCommand comm = new SqlCommand();
        comm.Connection = conn;
        comm.CommandText = sqlStatement;
        comm.Parameters.AddWithValue("serial_no", serial_no);
        comm.Parameters.AddWithValue("therapy_start", therapy_start);
        comm.Parameters.AddWithValue("machine_type", machine_type);
        comm.Parameters.AddWithValue("file_source", file_source);
        comm.Parameters.AddWithValue("dialog_version", dialog_version);
        comm.Parameters.AddWithValue("tlc_version", tlc_version);
        comm.Parameters.AddWithValue("versions", versions);
        comm.Parameters.AddWithValue("uploaded_on", uploaded_on);
        comm.Parameters.AddWithValue("uploaded_by", uploaded_by);
        comm.Parameters.AddWithValue("processed", processed);
        comm.Parameters.AddWithValue("user_original_file", user_original_file);
        comm.Parameters.AddWithValue("user_country", user_country);
        comm.Parameters.AddWithValue("user_comment", user_comment);
        comm.Parameters.AddWithValue("user_upload_reason", user_upload_reason);
        comm.Parameters.AddWithValue("user_location", user_location);
        myID = Convert.ToInt32(comm.ExecuteScalar());
    }
    catch (Exception ex)
    {
        return "ERROR: "+ex.Message;
    }
    finally
    {
        conn.Close();
    }

    return myID.ToString();
}

Sparx Systems Enterprise Architect + C#: Get all EA Elements of a package

Problem

All Elements of a package should be retrieved.

Approach – Ansatz

The method getElementsOfElement, which has been defined in the previous article is used to add all subelements of a package.

Lösung – Solution

public List<EA.Element> getElementsOfPackage(EA.Package package, string packageName)
{
    List<EA.Element> elementsOfPackage = new List<EA.Element>();
    // Only list the elements if the actual package is connected to a DOORS module
    if (package.Name == packageName)
    {
        foreach (EA.Element element in package.Elements)
        {
            elementsOfPackage.Add(element);
            elementsOfPackage.AddRange(getElementsOfElement(element));
        }
    }

    foreach (EA.Package subPackage in package.Packages)
    {
        elementsOfPackage.AddRange(getElementsOfPackage(subPackage, packageName));
    }
    return elementsOfPackage;
}

private List<EA.Element> getElementsOfElement(EA.Element actualElement)
{
    List<EA.Element> elementsOfElement = new List<EA.Element>();
    EA.Collection elements;
    elements = actualElement.Elements;

    foreach (EA.Element element in elements)
    {
        elementsOfElement.Add(element);
        elementsOfElement.AddRange(getElementsOfElement(element));
    }
    return elementsOfElement;
}

Sparx Systems Enterprise Architect + C#: Recursively get all elements and sub elements of an EA Element

Problem

All elements of an subelement should be catched

Approach – Solution

Recursively iterate through all subelements and AddRange (already a list) to the List.
The interuption of the recursion is, when an empty List is used as parameter for AddRange, because the loop will not be called where the AddRange-Method is in on next iteration.

Solution – Approach

private List<EA.Element> getElementsOfElement(EA.Element actualElement)
{
    List<EA.Element> elementsOfElement = new List<EA.Element>();
    EA.Collection elements;
    elements = actualElement.Elements;

    foreach (EA.Element element in elements)
    {
        elementsOfElement.Add(element);
        elementsOfElement.AddRange(getElementsOfElement(element));
    }
    return elementsOfElement;
}

Sparx Systems Enterprise Architect + C#: Get Top Package from selected Package

Problem

The top package of an Enterprise Architect Project EAP should be retrieved

Approach

Navigate to the Parent ID until the package return null.

Solution – Lösung

public EA.Package getTopPackage(EA.Package selectedPackage)
{
    EA.Package package = null;
    try
    {
        // If it has a parent it won't throw an error
        package = repository.GetPackageByID(selectedPackage.ParentID);
    }
    catch (System.Runtime.InteropServices.COMException)
    {
        // The selectedPackage is the top package
        package = selectedPackage;
    }
    // If this is not the top package, recall this function
    if (package != selectedPackage)
    {
        package = getTopPackage(package);
    }
    return package;
}

C#.NET: ZIP Dateien entpacken und im Zielverzeichnis ggf. überschreiben / Uncomrpess ZIP to a folder and overwrite existing

Problem

Die ZipFile.ExtractToDirectory(zip,target)-Methode in C# überschreibt keine vorhandenen Dateien, sondern schmeisst eine Exception.
The ZipFile.ExtractToDirectory(zip,target)-method in c# is not overwriting existing files, but throws an exception

Vorraussetzung – Prerequirements

.NET Framework der Version 4.5
Referenzen/References:
System.IO.Compression.dll
System.IO.Compression.FileSystem.dll

You have to import the using

using System.IO.Compression;

Ansatz – Approach

Durch die Iteration über das ZIP-Archiv lassen sich die einzelnen Dateien entpacken, wobei die Methode System.IO.Compression.ZipArchiveEntry.ExtractToFile(string path, bool overwrite) ein Überschreiben erlaubt.

The iteration on System.IO.Compression.ZipArchive with System.IO.Compression.ZipArchiveEntry.ExtractToFile(string path, bool overwrite) allows to overwrite existing files.

Lösung – Solution

public void ZipFileExtractToDirectory(string zipPath, string extractPath)
{
  using(System.IO.Compression.ZipArchive archive = ZipFile.OpenRead(zipPath))
  {
    foreach(ZipArchiveEntry entry in archive.Entries)
    {
      string completeFileName = Path.Combine(extractPath, entry.FullName);
      string directory = Path.GetDirectoryName(completeFileName);

      if (!Directory.Exists(directory))
      {
        Directory.CreateDirectory(directory);
      }
      entry.ExtractToFile(completeFileName, true);
    }
  }
}

ASP.NET asp:GridView gruppieren von identischen Spalten oder nach einer bestimmten Spalte / grouping identical GridView Rows/Cells or by column

Problem

Ein vorsortiertes asp:GridView (Screenshot: Original) soll nach einer Spalte (Screenshot Algorithmus 1) oder nach identischem Inhalt (Screenshot Algorithmus 2) sortiert werden.

Prämisse / Vorraussetzungen

  • Das GridView sollte vorher (z.B. mit ORDER BY-Klausel) vorsortiert werden um die bestmöglichen Ergebnisse zu erzielen.
  • Wenn nach einer Spalte gruppiert wird, sollte diese Spalte erstrangig (also erste Erwähnung in ORDER BY-Klausel) stattfinden.

Ansatz – Approach

  • Erschaffung eines Algorithmus, welcher über die RowSpan-Eigenschaft Zellen miteinander verbindet.
  • Vergleich ob der Text der Vorgängerspalte der gleiche ist
    • JA:
      • Unsichtbarschalten der aktuellen Zeilen
      • inkrement des RowSpan-Wertes der Vorgängerzeile
      • Vorgängerzeile ist nun die einzig Sichtbare
    • Nein: Weitermachen

Lösung – Solution

Vorgehensweise

1.) Auf das GridView klicken
2.) Im Objekt-Inspektor auf „Events/Ereignisse“ (also der Blitz) klicken
3.) Doppelklick auf das Ereignis „OnDataBound“
4.) in die erzeugte Methode kann der folgende Code kopiert werden

Algorithmus 1: GridView-Gruppierung nach einer Spalte

/****************************************
* ASP:GridView Grouping Algorithmus
* Quelle https://www.capri-soft.de/blog
****************************************/
// Nach dieser Spalte soll gruppiert werden
int k = 1;

// Für alle Zeilen (VON UNTEN NACH OBEN)
for (int i = GridView1.Rows.Count - 1; i > 0; i--)
{
  GridViewRow row = GridView1.Rows[i];
  GridViewRow previousRow = GridView1.Rows[i - 1];
  // Für alle Spalten
  for (int j = 0; j &lt; row.Cells.Count; j++)
  {
    if ((row.Cells[k].Text == previousRow.Cells[k].Text) && (row.Cells[j].Text == previousRow.Cells[j].Text))
    {
      if (previousRow.Cells[j].RowSpan == 0)
      {
        if (row.Cells[j].RowSpan == 0)
        {
          previousRow.Cells[j].RowSpan += 2;
        }
        else
        {
          previousRow.Cells[j].RowSpan =
          row.Cells[j].RowSpan + 1;
        }
        row.Cells[j].Visible = false;
      }
    }
  }
}

Algorithmus 2: GridView-Gruppierung für alle identischen Zellen einer GridView-Spalte

/****************************************
* asp:GridView Grouping Algorithmus
* Quelle: https://www.capri-soft.de/blog
****************************************/
// Für alle Zeilen (VON UNTEN NACH OBEN)
for (int i = GridView1.Rows.Count - 1; i > 0; i--)
{
  GridViewRow row = GridView1.Rows[i];
  GridViewRow previousRow = GridView1.Rows[i - 1];
  // Für alle Spalten
  for (int j = 0; j < row.Cells.Count; j++)
  {
    if (row.Cells[j].Text == previousRow.Cells[j].Text)
    {
      if (previousRow.Cells[j].RowSpan == 0)
      {
        if (row.Cells[j].RowSpan == 0)
        {
          previousRow.Cells[j].RowSpan += 2;
        }
        else
        {
          previousRow.Cells[j].RowSpan =
          row.Cells[j].RowSpan + 1;
        }
        row.Cells[j].Visible = false;
      }
    }
  }
}

ASP.NET: Generate Pie Charts over GET params from URL / Tortendiagramme über URL Get Request generieren

Problem

Es sollen Tortendiagramme in ASP.NET angezeigt werden.

Ansatz

Runterladen von

Die Diagramme können über einen Request-Parameter erstellt werden:

http://localhost:51241/PieChartGetParams.aspx?headline=Ich mag Bier&pieces=ein;20;komisches;50;Tortendiagramm;40

  • Headline: Ist die Überschrift des Tortendiagramms
  • Pieces: Abwechselnd durch Semikolon getrennt immer Tortenstück1;Wert1;Tortenstück2;Wert2;…;TortenstückN;WertN

Lösung – Solution

Laden Sie HighCharts runter und passen Sie untenstehenden Quellcode an:

<script src="pfad/zu/highcharts.js"></script>
<script src="charts/zu/exporting.js"></script>
<script type="text/javascript" src="Pfad/zu/jquery-1.4.1.min.js"></script>

Erstellen Sie eine ASP.NET-Seite mit folgendem Inhalt:

&lt;%@ Page Language="C#" AutoEventWireup="true" CodeFile="PieChartGetParams.aspx.cs" Inherits="PieChart" %&gt;
 
 <script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script><script src="charts/highcharts.js"></script><script type="text/javascript">
  $(function () {
    function drawPieChart(seriesData) {
       $('#container').highcharts({
	 chart: {
	   plotBackgroundColor: null,
           plotBorderWidth: null,
           plotShadow: false,
           type: 'pie'
	 },
	title: {
          text: '<%=Request.Params&#91;"headline"&#93; %>'
	},
	tooltip: {
          pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
        },
        plotOptions: {
           pie: {
            allowPointSelect: true,
            cursor: 'pointer',
            dataLabels: {
              enabled: true,
              format: '<b>{point.name}</b>: {point.y} ',
              style: {
               color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
              }
           }
        }
     },
     series: [{
       name: "Percentage",
       colorByPoint: true,
       data: seriesData
     }]
  });
 }

 function addToPieChart(arr, key, value)
 {
    var obj = {};
    obj.name = key;
    obj.y = value;
    arr.push(obj);
 }

 var arr = []

 <% if (Request.Params&#91;"pieces"&#93; != null) { string piecesParam = Request.Params&#91;"pieces"&#93;; char&#91;&#93; splitchar = { ';'}; int i = 0; string label = ""; foreach(string s in piecesParam.Split(splitchar)) { if(i%2==0) { label = s; } else { Response.Write("addToPieChart(arr, '" + label + "', " + s + ");"); } i++; } } %>

  var myJsonString = JSON.stringify(arr);
  var jsonArray = JSON.parse(JSON.stringify(arr));

  drawPieChart(jsonArray);
});
</script>
    
    <script src="charts/modules/exporting.js"></script>
 

 

 

 

 

ASP.NET C#: Windows Authentication / Single Sign On

Problem

In einer ASP.NET Seite möchte man den Windows-Anmeldebenutzer ermitteln.

Ansatz / Approach

In der Web-Anwendung muss man zunächst den Haken „Enable Anonymous Access“ entfernen und einen Haken bei „Enable Windows Authentication“ setzen.

Lösung / Solution

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Summary description for AuthenticationService
/// </summary>
public class AuthenticationService
{
   public AuthenticationService()
   {
	//
	// TODO: Add constructor logic here
	//
   }

    public string getUsername()
    {
        string windowsLogin = System.Web.HttpContext.Current.User.Identity.Name;

        if (windowsLogin == null) return "none";

        int hasDomain = windowsLogin.IndexOf(@"\");
        if (hasDomain > 0)
        {
            windowsLogin = windowsLogin.Remove(0, hasDomain + 1);
        } //end if 

        return windowsLogin;
    }
}