Quaerite, et invenietis

Eine von mir sehr häufig genutzt Klasse aus dem .NET-Framework ist die generische Liste System.Collections.Generic.List<T>. Allerdings bin ich es leid immer eine for oder foreach Schleife schreiben zu müssen, um ein bestimmtes Item aus der Liste zu finden.

Für einen solchen Fall bietet die Klasse die Methode Find(Predicate<T> match).

Ab .NET 3.5 ist diese Methode auf eine sehr schöne/kurze Schreibweise nutzbar. Mit Hilfe von einem Lambda-Ausdruck.

List<Person> myList = new List<Person>();
Person foundPerson = myList.Find(p => p.Vorname.Equals("Nils"));

p ist in dem Fall ein Item in der Liste und wird an das delegate p.Vorname.Equals(„Nils“) übergeben. Dies gibt dann einen boolschen Wert zurück. Wenn true, dann ist es das gesuchte Item und das Item wird zurückgegeben.

Die immer wieder gleich Schleifen haben so ein Ende 🙂

„Quaerite, et invenietis“ weiterlesen

Counter-Strike 1.6 – zBot Problem

Ich durfte heute für einen Bekannten Counter-Strike mit Steam installieren. Soweit so gut. Allerdings wollte er auch gegen Bots spielen und nicht nur gegen „diese ganzen freakigen Kellerkinder“ aus dem Internet. Ok, habe ich mir gedacht, einfach zBot draufkopieren … starten … fertig. Aber irgendwie wollte das nicht so wie ich es wollte. Ich habe die zBot Dateien in die Verzeichnisse „cstrike“ und „cstrike_german“ kopiert (keine Ahnung ob es in beide muss) und das Spiel gestartet. Ich konnte einfach über den Befehl „+commandmenu“ das Menü für zBot aufrufen und dem Spiel einen Bot hinzufügen.

Nachdem dies geschehen ist muss zBot beim ersten mal auf einer Map die Map analysieren. Wenn dies geschehen ist startet der Server neu. Das hat das Programm auch alles gemacht. Allerdings fing er dann sofort wieder an zu analysieren.

Nach ein paar Stunden Recherche im Internet konnte ich das Problem ausmachen. Da die Installation von Steam und Counter-Strike frisch war, existierte das Verzeichnis „maps“ noch nicht und er konnte die analysierten Daten wohl nicht korrekt ablegen. Also habe ich jeweils in den Verzeichnissen „cstrike“ und „cstrike_german“ ein Verzeichnis „maps“ erstellt und siehe da, die Map musste nur einmal analysiert werden.

Also Kurzfassung:

Wenn zBot immer wieder analysieren muss, einfach ein „maps“ Verzeichnis im Verzeichnis „cstrike“ bzw. „cstrike_german“ erstellen.

Serverseitigen Event bei verlassen einer ASP-Textbox auslösen

Die Standard-Textbox von ASP.NET unterstützt leider nicht das Event „OnLeave“ oder „OnBlur“. Mit Hilfe des Javascript-Events „onblur“ kann ein solches Event ermöglicht werden. Damit man dies nicht für jede Textbox implementieren muss habe ich daraus ein Steuerelement gemacht und es als DLL-Datei angehangen. Ihr könnt es einfach über die Toolbox von Visual Studio benutzen (Anleitung).

Im folgenden der Code:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Rapidev.Web.Controls
{
    public class rdTextbox : TextBox, IPostBackEventHandler
    {
        #region control events

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            if (!Page.ClientScript.IsClientScriptBlockRegistered("OnLeaveTextboxEvent"))
                Page.ClientScript.RegisterStartupScript(GetType(), "OnLeaveTextboxEvent", GetScript(), true);

            Attributes.Add("onblur", "OnBlurred('" + UniqueID + "','')");
        }

        #endregion

        #region OnLeave event

        public delegate void OnLeaveDelegate(object sender, EventArgs e);

        public event OnLeaveDelegate Leave;

        private void RaiseOnLeaveEvent()
        {
            if (Leave != null)
                Leave(this, EventArgs.Empty);
        }

        #endregion

        #region methods

        private string GetScript()
        {
            return "function OnBlurred(control, arg)\n{\n __doPostBack(control, arg);\n}";
        }

        #endregion

        #region Implementation of IPostBackEventHandler

        public void RaisePostBackEvent(string eventArgument)
        {
            RaiseOnLeaveEvent();
        }

        #endregion
    }
}

Download rdTextBox

Das Pendant zu „iif“ aus VB

Häufig genug muss man innerhalb seines Codes auf verschiedene Werte von Variablen reagieren. Um in einfachen Fällen nicht immer eine „if – else“ Anweisung schreiben zu müssen gibt es ein Pendant zu dem „iif“, welches aus VB (VisualBasic) bekannt ist. Der Operator „?:“.

Die Syntax ist folgende:

Bedingung ? true : false

Weiterführende Informationen sind hier im MSDN von Microsoft zu finden.

ASP.NET – Standardziel für die Eingabetaste innerherhalb einer Textbox

Häufig werden z.B. Formulare innerhalb von Webanwendungen benötigt. Diese bestehen oft aus mehreren Textboxen und Buttons. Viele Benutzer verwenden zum Abschluss eines Formulars die Eingabetaste, allerdings ist es ohne weitere Konfiguration dem Browser überlassen welchen Button er als Ziel für das Abschicken des Forumulars verwendet. Um diesem Problem Herr zu werden und für verschiedene Textboxen verschiedene Ziele festzulegen verwende ich folgenden Code.

Javascript:

function doClick(buttonName, e) {
	//the purpose of this function is to allow the enter key to
	//point to the correct button to click.
	var key;
	if (window.event)
		key = window.event.keyCode;     //IE
	else
		key = e.which;     //firefox
	if (key == 13) {
		//Get the button the user wants to have clicked
		var btn = document.getElementById(buttonName);
		if (btn != null) { //If we find the button click it
			btn.click();
			btn.focus();
			event.keyCode = 0
		}
	}
}

HTML-Markup:

<asp:TextBox ID="txtFilter" runat="server"></asp:TextBox>
<asp:Button ID="cmdFiltern" runat="server" Text="Filtern" OnClick="cmdFiltern_Click" />

CodeBehind (C#):

protected void Page_Load(object sender, EventArgs e)
{
	if (!IsPostBack)
		this.txtFilter.Attributes.Add("onkeypress", "doClick('" + cmdFiltern.ClientID + "',event)");
}

ReportViewer – Bericht als PDF aufrufen

Innerhalb einer Anwendung wollte ich gerne einen Report direkt exportiert als PDF-Datei aufrufen. Ich habe lange im Internet gesucht und habe viele nützliche Beiträge gefunden, allerdings habe ich kein Beispiel für meine Problemstellung gefunden. Da ich etwas unter zeitdrunk stand, musste ich mir etwas „einfaches“ einfallen lassen.

Das Problem lag darin, dass der ReportViewer die Daten/den Bericht erst einmal laden muss, bevor man ihn exportieren kann. Also klicke ich mit Hilfe von Javascript auf einen Button, der nachdem die Seite geladen wurde betätigt wird und den Bericht exportiert. Ich kann mir gut vorstellen, dass es eine wesentlich hübschere und bessere Methode dafür gibt, diese konnte ich aber leider nicht auf die schnelle finden.

„ReportViewer – Bericht als PDF aufrufen“ weiterlesen

Forms Application innerhalb des Konstruktors beenden

Innerhalb einer Anwendung habe ich mehrere Überprüfungen im Konstruktor hinterlegt, die dazu führen können, dass die Anwendung nicht geöffnet werden soll. Allerdings bringt es wenig, wenn man innerhalb des Konstruktor Application.Exit() aufruft. Application.Exit() durchläuft alle z.Z. geöffneten Forms und löst für jedes das FormClosing-Ereignis aus. Anschließend ruft es ThreadContext.ExitApplication() auf, was für die Forms des aktuellen Threads Dispose() aufruft. Das Problem dabei ist nur, dass das Hauptformular im eigenen Konstruktor noch gar kein Handle hat und somit kann Control.Dispose() nicht aufgerufen werden.

Deshalb verwendung ich zum Beenden der Anwendung folgende Methode:

Environment.Exit(0);

Methode zum Überprüfen und Beenden einer Anwendung

Während der Entwicklung einer Update-Anwendung bin ich auf das Problem gestoßen, dass ich überprüfen muss, ob eine Anwendung noch läuft. Weiterhin ist es „schick“ diese dann auch aus der Update-Anwendung schließen zu können. Folgende Methoden verwende ich dafür.

Um zu überprüfen ob eine Anwendung läuft:

/// <summary>
/// Überprüft ob eine Anwendung bereits läuft.
/// </summary>
/// <param name="applicationName">Anwendungsname.</param>
/// <returns>Läuft bereits.</returns>
public static bool IsApplicationAlreadyRunning(string applicationName)
{
    return System.Diagnostics.Process.GetProcessesByName(applicationName).Length > 0;
}

Um eine Anwendung zu beenden/schließen verwende ich folgende Methode:

/// <summary>
/// Versucht alle Instanzen einer Anwendung zu beenden.
/// </summary>
/// <param name="applicationName">Anwendungsname.</param>
/// <param name="killProcess">Gibt an, ob die Anwendung mit der .Kill() Methode beendet werden soll.</param>
public static void CloseApplication(string applicationName, bool killProcess)
{
    System.Diagnostics.Process[] appInstances = System.Diagnostics.Process.GetProcessesByName(applicationName);

    for (int i = 0; i < appInstances.Length; i++)
    {
        try
        {
            if (killProcess)
                appInstances[i].Kill();
            else
                appInstances[i].Close();
        }
        catch { }
    }
}

ASP.NET Button – Erst Javascript, dann C# Event

Es passiert leider ab und zu, dass man in einer Webanwendung Methoden hat, die etwas mehr Zeit zur Durchführung benötigen. Es gibt dann mehrere Möglichkeiten sicher zu stellen, dass der Benutzer den Prozess nicht unterbricht, bzw. auf die Fertigstellung der Methode wartet.

Um den Benutzer z.B. daran zu hindern ein weiteres mal auf einen Button zu klicken kann folgender Code-Snippet verwendet werden.

this.Button1.Attributes.Add("onclick", "javascript:" + this.Button1.ClientID +
".disabled=true;" + ClientScript.GetPostBackEventReference(this.Button1, string.Empty));

Nachdem die Javascriptfunktion ausgeführt wurde wird ein Postback von dem Button ausgeführt, als wenn er „ganz normal“ mit einem Server Side Event belegt wird.

Der Button im HTML-Markup sieht folgendermaßen aus:

<asp:Button ID="Button1" runat="server"
  Text="Button" OnClick="Button1_Click" />

Der Event, welcher vom Server ausgeführt wird sieht „ganz normal“ aus:

protected void Button1_Click(object sender, EventArgs e)
{
    // Insert Code here
}