Laden...

Forenbeiträge von mcdt Ingesamt 55 Beiträge

17.12.2014 - 12:06 Uhr
  • Neues Beispiel Projekt: Zyan Drench, ein Spiel für Android, 50K+ Downloads

Hi,

auch wenn das Spiel nur ein Nebenprdukt zu sein scheint: 👍
Was noch nett wäre bzgl. des Spiels: aktuell scheint es nur auf Telefonen zu laufen. Auf meinem Nexus 10 Tablet lässt sich das Spiel installieren und die App öffnen, aber nach einem Klick auf "Play against Android" schließt sich die App wieder.

01.04.2014 - 12:48 Uhr

Welche Klausel? Wie lautet sie?

Die Klausel lautet: aufs aktuelle Datum schauen 😉

29.06.2013 - 00:08 Uhr

Hallo,

zuerst mal sorry für den ungünstig gewählten Titel, ich grüble seit einiger Zeit an einem Problem und mir fällt keine bessere Beschreibung ein.

Ich versuche mein Problem auf das wesentliche zu abstarhieren.

Ich bekomme zur Laufzeit als Input den Pfad zu einer Datei.
Allerdings weis ich nicht wann, und in unregelmäßigen nicht planbaren Abständen kommen neue Pfade zu Dateien hinzu.

Ich muss diese Dateien, unter Umständen die sich zur Laufzeit ändern können, auf bestimmte "Kriterien" untersuchen.
Nehmen wir als Kriterien z.B.: die Dateigröße, die Dateiendung und den Namen der Datei. Die Anzahl der Kriterien ist fest und wird nicht geändert (in dem Beispiel hier 3)

Diese Kriterien bilden eine Art "Set".
Es gibt mehrere Sets die sich zur Laufzeit ändern können, ebenfals die Kriterien in einem Set.

Ist eine Datei einmal geprüft und anschließend wird ein Kriterium / Set geändert soll diese Datei nicht erneut auf diese geänderten Kriterien geprüft werden.

Jedes Set besteht aus der Info welches Kriterium getestet werden muss und wie das Kriterium lautet (Prüfe Endung auf "*.sln" ; Prüfe keinen Namen ; Prüfe Größe >1MB)

Alle Kriterien (die sich jedoch wie gesagt jederzeit ändern können) stehen mir im Programm zur Verfügung (List<Kriterium>)

Ich muss jede eingehende Datei auf alle aktuellen Kriterien testen.

Und genau an dieser Stelle hänge ich gerade.
Ich kann problemlos jede Kombination aller Kriterien prüfen ala:

  • Größe,Name,Endung;
  • !Göße,Name,Endung;
  • Größe,!Name,Endung;
  • Größe,Name,!Endung,
  • !Größe,!Name,Endung
  • !Größe,Name,!Endung
    ...
    allerdings erscheint mir das etwas aufwendig und vor allem entgegen DRY, da erst nach der Entscheidung welches Kriterium getestet werden muss die eigentliche Prüfung stattfindet.

Hat vielleicht jemand eine Idee diese Prüfung effizienter zu erledigen?

mfg

21.12.2012 - 17:58 Uhr

Hi,

habe vergessen zu erwähnen das sich die Differenz zur Laufzeit ändern kann, bzw sich sicher ändern wird.

Die Aussage das die vorgeschlagene Vorgehensweise für Performance unkritische Vorgänge I.O. ist reicht mir.

Danke!

21.12.2012 - 17:13 Uhr

Hallo,

ich habe folgende Aufgabenstellung:

Ein Objekt hat eine unbestimmte Anzahl an ChildObjects des selben Typs.
Das Objekt hat ein Property "compareValue" vom Typ <int>, demzufolge auch jedes ChildObject.
Die ChildObjekte sind in einer List<Objekt> enthalten.

Was ich möchte, ist bestimmen welches Childobjekt die geringeste Differenz "Objekt.compareValue - ChildObject.compareValues" besitzt.
Wenn mehrere Objekte die gleiche (geringste) Differenz besitzen ist mir egal welches Objekt ausgewählt wird.

Da es sich um maximal 100 Objekte handelt (welche dann jeweils 99 ChildObjekte besitzen) und die Performance nicht wichig ist könnte ich jedes ChildObjekt des "Parents" durchgehen und mir das Objekt mit der geringsten Differenz sichern.

Mich würde interessieren ob es eine "elgantere" Lösung gibt?

mfg

10.11.2012 - 15:14 Uhr

Starte deine Wartezeit einfach wenn du eine Response/ACK vom Server für deine Anfrage erhällst.

01.11.2012 - 15:09 Uhr

Hi,

das Problem ist gelöst.
Ursache waren mehrere Fehler meinerseits.

Ich hatte den Tabindex zwar auf 0, aber der Tabindex anderer Controls war ebenfals auf 0 (ich habe nicht darauf geachtet da ich davon ausgegangen bin das mir dies vom Compiler gesagt wird).
Weiterhin hatte ich einen Fehler ein par Zeilen vor dem aktivieren der Textbox, der dazu führte das eine Exception gefeuert wurde, und mein eigentlicher Code nicht ausgeführt wurde, das hatte ich vollkommen ignoriert.

Danke also für den Denkanstoß!!

01.11.2012 - 13:27 Uhr

Hallo,

ich möchte gerne folgendes realisieren:

Aus Form1 wird mittels "Form2.ShowDialog()" / "Form2.Show()" Form2 geöffnet.
In Form2 befindet sich eine Textbox welche ich beim öffnen von Form2 Fokusieren/ Selektieren möchte, sodass direkt nach dem öffnen der Form2 ohne weitere Aktion Text in diese Textbox eingegeben werden kann.

Dazu habe ich im Load bzw Shown Event von Form2 "textbox.Focus()" bzw "textbox.Select()" aufgerufen, allerdings ist der Eingabecursor erst nach drücken der TAB Taste sichtbar, und somit kann auch erst anschließend Text eingegeben werden.

Google hat mir nicht weitergeholfen, da ich dort Beiträge gefunden habe welche beschreiben das das Problem im "Shown" Event der Form (Form2) nicht mehr auftreten sollte.
Die Forensuche hat folgenden Beitrag zum Vorschein gebracht: [erledigt] Focus beim Laden auf eine TextBox setzen [==> FocusManager.FocusedElement binden], dort handelt es sich allerdings im WPF und nicht um WinForms.

Kann mir evtl jemand weiterh helfen.

mfg

14.10.2012 - 22:09 Uhr

zwar kein buch, aber trotzdem interessant: Design Guidelines

04.10.2012 - 10:53 Uhr

Hallo,

anbei eine Version mit welcher die geposteten Testfälle erfolgreich durchlaufen werden.
Ansatt einer 0 wird allerdings eine Exception geworfen.
Bei einem speziellen Fall dürfte der Code evtl noch Probleme haben, aber diesen kann ich aktuell aufgrund von Zeitmangel nicht vor heute Abend beheben.


       public static TimeSpan SubtractEx(DateTime start, DateTime end, Dictionary<DayOfWeek, IList<TimeSpan>> timelist)
        {
            TimeSpan _result = new TimeSpan();
     
            // *** Aenderung ***
            TimeSpan _totalDaysBetween = end.Date.Subtract(start.Date);

            if ( end.Subtract(start) < new TimeSpan())
                throw new ArgumentException("Fehler! \n Ungueltige Zeiangabe");

            IList<TimeSpan> _firstList = new List<TimeSpan>();
            IList<TimeSpan> _secondList = new List<TimeSpan>();
            IList<TimeSpan> _tempList = new List<TimeSpan>();

            DateTime _firstDate = new DateTime();
            DateTime _secondDate = new DateTime();
            DateTime _tempDate = new DateTime();


            // *** Aenderung ***
            switch (_totalDaysBetween.Days)
            {
                case 0:
                    //Startdatum == Enddatum
                    timelist.TryGetValue(start.DayOfWeek, out _firstList);
                    _result = _result.Add(GetTimeSpanBetween(start, end, _firstList));
                    break;
                //-------------------------------------------------------------------------------------------
                case 1:
                    // Startdatum + 1Tag = Enddatum
                    _firstDate = new DateTime(start.Year,
                                              start.Month,
                                              start.Day,
                                              23, 59, 59);

                    _secondDate = new DateTime(end.Year,
                                               end.Month,
                                               end.Day,
                                               00, 00, 00);

                    timelist.TryGetValue(start.DayOfWeek, out _firstList);
                    timelist.TryGetValue(end.DayOfWeek, out _secondList);
                    _result = _result.Add(GetTimeSpanBetween(start, _firstDate, _firstList));
                    _result = _result.Add(GetTimeSpanBetween(_secondDate, end, _secondList));
                    break;
                //-------------------------------------------------------------------------------------------
                case 2:
                    // Startdatum + 2Tage = Enddatum --> kein "voller" Tag dazwischen
                    _firstDate = new DateTime(start.Year,
                                              start.Month,
                                              start.Day,
                                              23, 59, 59);

                    _secondDate = new DateTime(end.Year,
                                               end.Month,
                                               end.Day,
                                               00, 00, 00);

                    _tempDate = start.AddDays(1);
                    _tempDate = new DateTime(_tempDate.Year,
                                             _tempDate.Month,
                                             _tempDate.Day,
                                             00, 00, 00);

                    DateTime _tempDateEnd = new DateTime(_tempDate.Year,
                                                         _tempDate.Month,
                                                         _tempDate.Day,
                                                         23, 59, 59);

                    timelist.TryGetValue(start.DayOfWeek, out _firstList);
                    timelist.TryGetValue(end.DayOfWeek, out _secondList);
                    timelist.TryGetValue(_tempDate.DayOfWeek, out _tempList);

                    _result = _result.Add(GetTimeSpanBetween(start, _firstDate, _firstList));
                    _result = _result.Add(GetTimeSpanBetween(_secondDate, end, _secondList));
                    _result = _result.Add(GetTimeSpanBetween(_tempDate, _tempDateEnd, _tempList));
                    break;
                //-------------------------------------------------------------------------------------------
                default:
                    // Startdatum + 3Tage + X = Enddatum
                    _firstDate = new DateTime(start.Year,
                                              start.Month,
                                              start.Day,
                                              23, 59, 59);

                    _secondDate = new DateTime(end.Year,
                                               end.Month,
                                               end.Day,
                                               00, 00, 00);

                    timelist.TryGetValue(start.DayOfWeek, out _firstList);
                    timelist.TryGetValue(end.DayOfWeek, out _secondList);

                    _result = _result.Add(GetTimeSpanBetween(start, _firstDate, _firstList));
                    _result = _result.Add(GetTimeSpanBetween(_secondDate, end, _secondList));

                    //Alle Tage zwischen Startdatum+1 und Enddatum-1 ermitteln
                    DateTime _firstRelevantDay = start.AddDays(1);
                    DateTime _lastRelevantDay = end.Subtract(new TimeSpan(24, 0, 0));

                    _firstRelevantDay = new DateTime(_firstRelevantDay.Year,
                                                     _firstRelevantDay.Month,
                                                     _firstRelevantDay.Day,
                                                     00, 00, 00);

                    _lastRelevantDay = new DateTime(_lastRelevantDay.Year,
                                                    _lastRelevantDay.Month,
                                                    _lastRelevantDay.Day,
                                                    23, 59, 59);

                    int _fullDays = _lastRelevantDay.Subtract(_firstRelevantDay).Days;
                    _fullDays++;

                    // ganze + angebrochene wochen ermittlen
                    int _weeks = _fullDays / 7;
                    int _daysOverWeeks = _fullDays % 7;

                    _tempDate = _firstRelevantDay;
                    Dictionary<DayOfWeek, int> _dayOrder = new Dictionary<DayOfWeek, int>();
                    for (int i = 0; i < 7; i++)
                    {
                        if (i <= _fullDays)
                            _dayOrder.Add(_tempDate.AddDays(i).DayOfWeek, i);
                    }

                    if (_fullDays <= 7)
                    //Keine volle Woche zwishen start(+1) und ende(-1)
                    {
                        for (int i = 1; i <= _fullDays; i++)
                        {

                            timelist.TryGetValue(_firstRelevantDay.AddDays(i - 1).DayOfWeek, out _tempList);
                            DateTime _currentStart = _firstRelevantDay;
                            DateTime _currentEnd = new DateTime(_currentStart.Year,
                                                                _currentStart.Month,
                                                                _currentStart.Day,
                                                                23, 59, 59);

                            _result = _result.Add(GetTimeSpanBetween(_currentStart, _currentEnd, _tempList));
                        }
                    }
                    //mindestens 1tag ist dopplet vorhanden (excl start und ende)
                    else
                    {
                        for (int i = 0; i < 7; i++)
                        {
                            int _factor = _weeks;
                            if (i < _daysOverWeeks)
                                _factor++;

                            timelist.TryGetValue(_firstRelevantDay.AddDays(i).DayOfWeek, out _tempList);

                            DateTime _start = _firstRelevantDay;
                            DateTime _end = new DateTime(_start.Year,
                                                         _start.Month,
                                                         _start.Day,
                                                         23, 59, 59);

                            TimeSpan _tempSpan = GetTimeSpanBetween(_start, _end, _tempList);
                            TimeSpan _multiplied = new TimeSpan(_tempSpan.Days * _factor,
                                                                _tempSpan.Hours * _factor,
                                                                _tempSpan.Minutes * _factor,
                                                                _tempSpan.Seconds * _factor);

                            _result = _result.Add(_multiplied);
                        }
                    }

                    break;
            }
            return _result;
        }

        private static TimeSpan GetTimeSpanBetween(DateTime start, DateTime end, IList<TimeSpan> timelist)
        {
            TimeSpan _result = new TimeSpan();

            //timelist ist NULL  wenn kein eintrag fuer den Wochentag im Dict --> leeren TimeSpan zurück geben
            if (timelist != null)
            {
                for (int i = 0; i < timelist.Count; i += 2)
                {
                    //(Startzeit < TimeListZeit[n]) + (Endzeit < TimeListZeit[n+1]) --> TimeListZeit[n] + Endzeit nehmen
                    if ((start.TimeOfDay <= timelist[i]) && (end.TimeOfDay <= timelist[i + 1]))
                    {
                        _result = _result.Add(end.TimeOfDay.Subtract(timelist[i]));
                    }
                    //(Startzeit < TimeListZeit[n]) + (Endzeit > TimeListZeit[n+1]) --> TimeListZeit[n] + TimeListZeit[n+1] nehmen
                    else if ((start.TimeOfDay <= timelist[i]) && (end.TimeOfDay >= timelist[i + 1]))
                    {
                        _result = _result.Add(timelist[i + 1].Subtract(timelist[i]));
                    }
                    //(Startzeit > TimeListZeit[n]) + (Endzeit < TimeListZeit[n+1]) --> Startzeit       + Endzeit nehmen
                    else if ((start.TimeOfDay >= timelist[i]) && (end.TimeOfDay <= timelist[i + 1]))
                    {
                        _result = _result.Add(end.TimeOfDay.Subtract(start.TimeOfDay));
                    }
                    //(Startzeit > TimeListZeit[n]) + (Endzeit > TimeListZeit[n+1]) --> Startzeit       + TimeListZeit[n+1] nehmen
                    else if ((start.TimeOfDay >= timelist[i]) && (end.TimeOfDay >= timelist[i + 1]))
                    {
                        _result = _result.Add(timelist[i + 1].Subtract(start.TimeOfDay));
                    }
                    else
                    {
                        throw new ArgumentException("Fehler! \n Ungueltige Zeiangabe");
                    }
                }
            }
            return _result;
        }

Meine Ausgabe mit dem geposteten Testfall lautet:


Exception
5
13
21
29
31
31
37
45
53
61
---
Exception
Exception
3
11
19
26
26
27
35
43
51


Edit:
Habe den Code editiert.
Da nur 2 Zeilen geändert wurden habe ich keinen neuen Post erstellt.
Aus:


int _totalDaysBetween = end.DayOfYear - start.DayOfYear;

Wird:


// *** Aenderung ***
TimeSpan _totalDaysBetween = end.Date.Subtract(start.Date);

und aus:


switch (_totalDaysBetween)

wird:


// *** Aenderung ***
switch (_totalDaysBetween.Days)

03.10.2012 - 21:10 Uhr

Hi,

dann würde ich mal einen Vorschlag posten.
Der Code dürfte für die meisten nicht sehr attraktiv wirken.
Kritik nehme ich gerne per PM entgegen 😃

Ich habe den Code zwar etwas aufgehübscht, aber das einige Stellen sich wiederholen ist mir bewusst, wollte ich aber nicht noch ausbessern.


		public static TimeSpan SubtractEx(DateTime start, DateTime end, Dictionary<DayOfWeek, IList<TimeSpan>> timelist)
		{
			TimeSpan _result = new TimeSpan();
			int _totalDaysBetween = end.Subtract(start).Days;

			if ( _totalDaysBetween < 0 )
				throw new ArgumentException("Fehler! \n Ungueltige Zeiangabe");

			IList<TimeSpan> _firstList = new List<TimeSpan>();
			IList<TimeSpan> _secondList = new List<TimeSpan>();
			IList<TimeSpan> _tempList = new List<TimeSpan>();

			DateTime _firstDate = new DateTime();
			DateTime _secondDate = new DateTime();
			DateTime _tempDate = new DateTime();

			switch ( _totalDaysBetween )
			{
				case 0:
				//Startdatum == Enddatum
				timelist.TryGetValue(start.DayOfWeek, out _firstList);
				_result = _result.Add(GetTimeSpanBetween(start, end, _firstList));
				break;
				//-------------------------------------------------------------------------------------------
				case 1:
				// Startdatum + 1Tag = Enddatum
				_firstDate = new DateTime(start.Year,
													start.Month,
													start.Day,
													23, 59, 59);

				_secondDate = new DateTime(end.Year,
													end.Month,
													end.Day,
													00, 00, 00);

				timelist.TryGetValue(start.DayOfWeek, out _firstList);
				timelist.TryGetValue(end.DayOfWeek, out _secondList);
				_result = _result.Add(GetTimeSpanBetween(start, _firstDate, _firstList));
				_result = _result.Add(GetTimeSpanBetween(_secondDate, end, _secondList));
				break;
				//-------------------------------------------------------------------------------------------
				case 2:
				// Startdatum + 2Tage = Enddatum --> kein "voller" Tag dazwischen
				_firstDate = new DateTime(start.Year,
													start.Month,
													start.Day,
													23, 59, 59);

				_secondDate = new DateTime(end.Year,
													end.Month,
													end.Day,
													00, 00, 00);

				_tempDate = start.AddDays(1);
				_tempDate = new DateTime(_tempDate.Year,
												_tempDate.Month,
												_tempDate.Day,
												23, 59, 59);

				DateTime _tempDateEnd = new DateTime(_tempDate.Year,
																_tempDate.Month,
																_tempDate.Day,
																23, 59, 59);

				timelist.TryGetValue(start.DayOfWeek, out _firstList);
				timelist.TryGetValue(end.DayOfWeek, out _secondList);
				timelist.TryGetValue(_tempDate.DayOfWeek, out _tempList);

				_result = _result.Add(GetTimeSpanBetween(start, _firstDate, _firstList));
				_result = _result.Add(GetTimeSpanBetween(_secondDate, end, _secondList));
				_result = _result.Add(GetTimeSpanBetween(_tempDate, _tempDateEnd, _tempList));
				break;
				//-------------------------------------------------------------------------------------------
				default:
				// Startdatum + 3Tage + X = Enddatum
				_firstDate = new DateTime(start.Year,
													start.Month,
													start.Day,
													23, 59, 59);

				_secondDate = new DateTime(end.Year,
													end.Month,
													end.Day,
													00, 00, 00);

				timelist.TryGetValue(start.DayOfWeek, out _firstList);
				timelist.TryGetValue(end.DayOfWeek, out _secondList);

				_result = _result.Add(GetTimeSpanBetween(start, _firstDate, _firstList));
				_result = _result.Add(GetTimeSpanBetween(_secondDate, end, _secondList));

				//Alle Tage zwischen Startdatum+1 und Enddatum-1 ermitteln
				DateTime _firstRelevantDay = start.AddDays(1);
				DateTime _lastRelevantDay = end.Subtract(new TimeSpan(24, 0, 0));

				_firstRelevantDay = new DateTime(_firstRelevantDay.Year,
															_firstRelevantDay.Month,
															_firstRelevantDay.Day,
															00, 00, 00);

				_lastRelevantDay = new DateTime(_lastRelevantDay.Year,
															_lastRelevantDay.Month,
															_lastRelevantDay.Day,
															23, 59, 59);

				int _fullDays = _lastRelevantDay.Subtract(_firstRelevantDay).Days;
				_fullDays++;

				// ganze + angebrochene wochen ermittlen
				int _weeks = _fullDays / 7;
				int _daysOverWeeks = _fullDays % 7;

				_tempDate = _firstRelevantDay;
				Dictionary<DayOfWeek, int> _dayOrder = new Dictionary<DayOfWeek, int>();
				for ( int i = 0 ; i < 7 ; i++ )
				{
					if ( i <= _fullDays )
						_dayOrder.Add(_tempDate.AddDays(i).DayOfWeek, i);
				}

				if ( _fullDays <= 7 )
				//Keine volle Woche zwishen start(+1) und ende(-1)
				{
					for ( int i = 1 ; i <= _fullDays ; i++ )
					{

						timelist.TryGetValue(_firstRelevantDay.AddDays(i - 1).DayOfWeek, out _tempList);
						DateTime _currentStart = _firstRelevantDay;
						DateTime _currentEnd = new DateTime(_currentStart.Year,
																		_currentStart.Month,
																		_currentStart.Day,
																		23, 59, 59);

						_result = _result.Add(GetTimeSpanBetween(_currentStart, _currentEnd, _tempList));
					}
				}
				//mindestens 1tag ist dopplet vorhanden (excl start und ende)
				else
				{
					for ( int i = 0 ; i < 7 ; i++ )
					{
						int _factor = _weeks;
						if ( i < _daysOverWeeks )
							_factor++;

						timelist.TryGetValue(_firstRelevantDay.AddDays(i).DayOfWeek, out _tempList);

						DateTime _start = _firstRelevantDay;
						DateTime _end = new DateTime(_start.Year,
																_start.Month,
																_start.Day,
																23, 59, 59);

						TimeSpan _tempSpan = GetTimeSpanBetween(_start, _end, _tempList);
						TimeSpan _multiplied = new TimeSpan(_tempSpan.Days * _factor,
																		_tempSpan.Hours * _factor,
																		_tempSpan.Minutes * _factor,
																		_tempSpan.Seconds * _factor);

						_result = _result.Add(_multiplied);
					}
				}

				break;
			}
			return _result;
		}

		private static TimeSpan GetTimeSpanBetween(DateTime start, DateTime end, IList<TimeSpan> timelist)
		{
			TimeSpan _result = new TimeSpan();

			//timelist ist NULL  wenn kein eintrag fuer den Wochentag im Dict --> leeren TimeSpan zurück geben
			if ( timelist != null )
			{
				for ( int i = 0 ; i < timelist.Count ; i += 2 )
				{
					//(Startzeit < TimeListZeit[n]) + (Endzeit < TimeListZeit[n+1]) --> TimeListZeit[n] + Endzeit nehmen
					if ( ( start.TimeOfDay <= timelist[i] ) && ( end.TimeOfDay <= timelist[i + 1] ) )
					{
						_result = _result.Add(end.TimeOfDay.Subtract(timelist[i]));
					}
					//(Startzeit < TimeListZeit[n]) + (Endzeit > TimeListZeit[n+1]) --> TimeListZeit[n] + TimeListZeit[n+1] nehmen
					else if ( ( start.TimeOfDay <= timelist[i] ) && ( end.TimeOfDay >= timelist[i + 1] ) )
					{
						_result = _result.Add(timelist[i + 1].Subtract(timelist[i]));
					}
					//(Startzeit > TimeListZeit[n]) + (Endzeit < TimeListZeit[n+1]) --> Startzeit       + Endzeit nehmen
					else if ( ( start.TimeOfDay >= timelist[i] ) && ( end.TimeOfDay <= timelist[i + 1] ) )
					{
						_result = _result.Add(end.TimeOfDay.Subtract(start.TimeOfDay));
					}
					//(Startzeit > TimeListZeit[n]) + (Endzeit > TimeListZeit[n+1]) --> Startzeit       + TimeListZeit[n+1] nehmen
					else if ( ( start.TimeOfDay >= timelist[i] ) && ( end.TimeOfDay >= timelist[i + 1] ) )
					{
						_result = _result.Add(timelist[i + 1].Subtract(start.TimeOfDay));
					}
					else
					{
						throw new ArgumentException("Fehler! \n Ungueltige Zeiangabe");
					}
				}
			}
			return _result;
		}

30.09.2012 - 23:47 Uhr

Hallo gfoidl,

schade.
Trotzdem Danke für die Antwort und fürs raussuchen des Links.
Kann ich bestimmt später mal gebrauchen.

mfg

30.09.2012 - 23:12 Uhr

Hallo,

ich möchte gerne ein Snippet erstellen welches mir einen "Kompletten" (ich weis die korrekt Bezeichnung leider nicht) Propertyzugriff erstellt.

Gemeint ist das ein privates Feld ersetllt wird und der Zugriff auf dieses dann über ein Public Property möglich ist.
Das private Feld sollte mit einem "_" vorangestellt werden und anschließend sollte der erste Buchstabe klein geschrieben sein.

Sprich Ziel ist folgendes Konstrukt:


			private int _test;
			public int Test{
				get{
					return _test;
				}

				set{
					if ( value != _test ){
						_test = value;
					}
				}

			}

Mit folgendem Snippet erreicht ich allerdings nicht mein gewünschtes Ergebnis.
Hier das Snippet:


      <Code Language="csharp">
        <![CDATA[      
          private $type$  _$property$;
          public $type$ $property$
          {
            get
            {
              return _$property$;
            }
            set
            {
              if(value != _$property$)
              {
                _$property$ = value;
              }
            }
          }
        ]]>
      </Code>

und hier das erreichte Ergebnis:


          private int  _Test;
          public int Test{
            get{
              return _Test;
            }
            set{
              if(value != _Test){
                _Test = value;
              }
            }
          }

Was selbstverständlich nicht passier,t ist das das private Feld klein geschrieben wird.
Grund ist, das keine *.ToLowet() konvertierung des Eigenschaftsnamen für das private Feld stattfindet.

Die Frage ist nun, wie kann ich im Snippet das private Feld zu einem kleinen Wort konvertieren, sodas das gewünschte Konstrukt ( siehe erster Codeausschnitt) entsteht?

mfg

26.09.2012 - 20:15 Uhr

Hallo,

die Ursache war wie unconnected geschrieben hat die unterschiedlichen Berechtigungen / installierten Drucker der User des Dienstes.

herbivore:
Du hast recht das an diesem Problem das entscheidende war herauszufinden wo der Unterschied zw dem korrekt ausführbarem und dem nicht ausführbarem Code ist, allerdings wäre ich auch mithilfe des gepostetend Links nicht darauf gekommen bin das es an der Userberchtigung liegt mit der der Dienst gestartet wird, auch wenn es vielleicht für manche naheliegend ist, wäre ich nicht drauf gekommen. Jetzt weis ich's jedenfals 😃

Nichtsdestotrotz werde ich mit dieser Erkenntnis eine WinForms Anwendung erstellen.

Danke an alle.

mfg

26.09.2012 - 15:20 Uhr

Hi,

naja, ich denke nicht nur das der EventHandler ausgeführt wird, ich bin mir sicher, da dieser Code 1:1 in einer WinForms anwendung funktioniert.
Schließlich wird zwischen registrieren und deregistrieren des Events die Print() Methode aufgerufen.

26.09.2012 - 14:02 Uhr

Hallo,

ich habe einen Windows Dienst erstellt, und möchte aus diesem heuraus Dokumnete drucken.

Kleiner Hintergrund:
Es gibt von z.B. HP-Druckern das Gimmick das Mails an eine bestimmte Mail Adresse geschickt werden können, welche wenn der Drucker am Netz hängt, automatisch ausgedruckt werden.
Das ganze möchte ich ebenfals realisieren. Da der relevante Drucker nicht am Netz hängt, sondern per LAN mit einem Notebook verbunden ist möchte ich auf dem Notebook einen Dienst laufen lassen welcher alle X Minuten eine bestimmte Mail Adresse auf neue Mails prüft.
Dazu nutze ich die OpenPoP Library. Das abrufen der Mails sowie das abspeichern der Anhänge funktioniert auch problemlos.

Anschließend unterscheide ich die zu druckenden Anhänge (.doc,.xls,.pdf,.bmp usw.) und drucke diese entsprechend aus.

Für das Drucken habe ich mir eine Erweiterungsmethode zur Klasse "FileInfo" geschrieben und starte den Druckvorgang aus dieser Erweiterung heraus.

Jetzt habe ich durch Logeinträge im Dienst erausgefunden das der Dienst nur bis zu dieser Erweiterungsmehtode läuft, dort "verharrt" und die Dateien nicht ausgedruckt werden.
In einer Test Windows Forms Anwendung läuft das Ganze Problemlos, sprich die Dokumente werde gedruckt.

Scheitert mein Vorhaben daran das aus Diensten generell nicht gedruckt werden kann oder kann das noch andere Ursachen haben?

Anbei ein Auszug aus erwähnter Erweiterungsmethode, welche zwar Aufgerufen aber nicht abgearbeitet wird:


	public static class MyHelpers
	{
		public static void  TryPrint(this FileInfo FileInfo)
		{
			if ( FileInfo.Extension.ToLower() == ".png" ||
				FileInfo.Extension.ToLower() == ".bmp" ||
				FileInfo.Extension.ToLower() == ".jpg" ||
				FileInfo.Extension.ToLower() == ".jpeg" )
			{
				PrintDocument _imagePrintDocument = new PrintDocument();
				_imagePrintDocument.DocumentName = FileInfo.FullName;
				_imagePrintDocument.PrintPage+=new PrintPageEventHandler(_imagePrintDocument_PrintPage);
				_imagePrintDocument.Print();
				_imagePrintDocument.PrintPage -= new PrintPageEventHandler(_imagePrintDocument_PrintPage);
				_imagePrintDocument.Dispose();
			}
		}

		private static void _imagePrintDocument_PrintPage(object sender, PrintPageEventArgs e)
		{
			Image _image = Image.FromFile((sender as PrintDocument).DocumentName);
			e.Graphics.DrawImage(_image, new System.Drawing.Rectangle(new System.Drawing.Point(0, 0), new Size(_image.Width, _image.Height)));
		}
	}

21.09.2012 - 08:36 Uhr

hi,

ich gehe über keinen PrintServer.
Anpingen habe ich verworfen, da ich die IP des Druckers nicht kenne und sich diese auch ändern kann, und ich möchte nicht das Netzwerk durchsuchen ob der Drucker erreichbar ist.

Weiterhin kann ich mir nicht vorstellen das es keine Boadmittel gibt zu ermitteln ob der Drucker erreichbar ist.

Wenn es nicht anders geht werde ich wohl auf das anpingen zurück greifen müssen.

mfg

20.09.2012 - 18:38 Uhr

Hallo,

ich möchte gerne Dateien drucken.
Dazu muss ich vor dem Druck prüfen ob der Drucker (Standarddrucker) erreichbar ist.

Ich habe schon im Netz gesucht und 2 vermeindliche Lösungen gefunden, die aber beide warum auch immer, bei mir nicht funktionieren.

Leider gibt es zu dem Thema generell recht wenig Lesestoff im Netz, aber vielleicht hat ja trotzdem jemand eine Idee wie ich prüfen kann ob ein bestimmter Drucker erreichbar ist.

Anbei die beiden vermeindlichen Lösungen: Prüfen ob Netzwerkdrucker erreichbar

Mit "funktioniert nicht" meine ich, das mir die Methode "PrinterIsOnline" TRUE zurück liefert, obwohl der relevante Drucker nicht erreichbar sein kann (LAN Kabel am PC gezogem).
Selbes Verhalten des "IsValid" Propertys der PrintDocument Klasse im o.g. Thread.

Hat jemand eine Idee?

mfg

10.09.2012 - 17:40 Uhr

Ja, ich meine eine Textdatei welche mit dem Editor Notepad ersetllt / formatiert wurde.

Gibt es dann vielleicht die möglichkeit (wie z.B.: mit Office Dokumenten) die Notebook-Exe zu starten und von dort aus das Dokument zu öffnen und anschließend auszudrucken?
Meines Wissens nach passiert ja genau das selbe mit Den "Microsoft.Office.Interop.Word. ..." Klassen wenn dort ein Dokument geöffnet und anschließend über die "PrintOut()" Methode gedruckt wird.

mfg

10.09.2012 - 10:05 Uhr

Hallo,

ich möchte gerne diverse Dateitypen drucken. Unter anderem auch *.txt Dateien.
Da diese ja auch eingeschränkt formatierbar sind (Schrifttyp + Schriftgröße) wollte ich fragen wie man diese eingestellte Formatierung bei einem Druck der Datei erhalten kann?

Aktuell erzeuge ich ein Printdocument, und rufe die Methode Printducument.Print() auf.
Im Eventhandle "PrintPage" lese ich den Stream der Datei ein, und "zeichne" den Text des Streams.

Dabei geht allerdings der eingestellte Formatierung samt Schriftgröße verloren.

Die Frage ist also wie können *.txt Datei gedruckt werden ohne die eingestellte Formatierung zu verlieren?

mfg

06.08.2012 - 07:03 Uhr

Besten Dank für die Tipps und Hinweise.
Ich denke ich werde anfangs versuchen den Kostengünstigen Weg wählen und genau wie Abt das NAS System direkt an die EasyBox hängen.
Sollte sich das als zu langsam erweisen kann ich im nachhinein immernoch einen zusätlichen GB Switch + GB-AP kaufen.

mfg

04.08.2012 - 16:31 Uhr

Hi,

ich habe schon etwas im Netz gesucht, aber nur Threas gefunden die irgendwann eingeschlafen sind ohne einen Lösungsvorschlag.

Es geht um folgendes:
Ich habe einen Festplattencrash hinter mir und möchte jetzt ene Backup und Media-Ablage Lösung über NAS an einer Vodafone EasyBox 803 bei mir zuhause installieren.
Der Zugriff auf diese NAS sollte vorwiegend über WLAN 802.11 b/g erfolgen, da ich noch Notebooks ohne 802.11n habe.

Die Entscheidene Frage ist: welche Komponenten sind notwendig um eine Performante Lösung zu erziehlen?

Ich habe gelesen das die EasyBox-Switch Funktion langsam und daher für den NAS Zugriff unbrauchbar ist.

Die Idee wäre also einen Gigabit Switch an die EasyBox zu hängen, und das NAS an diesen GB-Switch zu hängen. Reicht dieses "einfache" Lösung und brächte ich dann noch einen weiteren AccesPoint mit Gigabit Anschluss um über diesen AP an die NAS zu kommen?
Der Zugriff über die EasyBox --> NAS würde mich ja wieder "ausbremsen" oder?

Wenn jemand mit gleichwertigen Komponenten erfolgreich ein NAS eingerichtet hat währe ich über Tipps / Hinweise dankbar.

mfg

23.05.2012 - 13:22 Uhr

Hi,

besten Dank für die Antworten.
Ich denke ich werde mich aufgrund der zahlreichen positiven Äuserungen für einen Laserdrucker entscheiden.

mfg

22.05.2012 - 19:53 Uhr

Hallo,

ich habe vor mir demnächst einen Drucker zu kaufen.
Ich brauche ihn lediglich Privat, und es sollen nur Dokumente ausgedruckt werden, also weder Fotos noch sonstige Angelegenheiten bei denen wirklich gute Druckqualität wichtig ist.
Farbe sollte er aber schon drucken können.
Wieviele Seiten ich drucke schwankt stark. Als Richtmas würde ich auf ~30 - 50 pro Monat schätzen, aber es kann auch Monate geben ohne einen Ausdruck.
Er wird hauptsächlich für ein Studium und anfallende Kosten für Kopien / Skripte / Unterlagen benötigt.
Da ich schonmal in einer wichtigen Angelegenheit vor einem Druck mit eingetrockneter Tinte stand wollte ich mir einen Laserdrucker kaufen.
Jetzt hat mir allerdings ein Kollege erzählt das er das selbe schon mit einem Laserdrucker erlegbt hat, also eingetrockneter Toner.

Weiterhin sollte das Gerät Kopien/Scannen können, aber das sollte an der Stelle nicht weiter relevant sein.

Würde es bei einem Tintenstrahldrucker ausreichen regelmäßig Testseiten zu drucken um das austrocknen zu verhinder?

Hat jemand einen Rat für mich ?

mfg

07.04.2012 - 18:38 Uhr

Hallo,

ich habe einen Polygonzug und Möchte herausfinden ob sich der Mauscursor innerhalb oder Außerhalb dieses Polygonzuges befindet.

Um es etwas zu Präzessieren: Es handelt sich bei dem Polygonzug um die Umrisse eines "3D-würfels".

Ich habe alle "äußeren" Eckpunkte ermittelt und diese einer GraphicsPath Instanz mittels "GraphicsPath .AddPolygon( )" zugewiesen.
Mittels "GraphicsPath .GetBounds().Contains( ) )" erhalte ich nicht das korrekte Ergebnis, da diese Methode anscheinend prüft ob der angegebene Punkt in einem Rechteck, gebildet aus dem Polygon, liegt.

Die Frage also, wie kann ich heruasfinden ob ein Punkt innerhalb eines Polygonzuges ist?

mfg

20.03.2012 - 11:37 Uhr

Danke!

genau das war das Problem!
Steht eigentlich auch Indirekt in der Tabelle im verlinktem Wikipedia das der Moderator immer eine Tür öffnet hinter der eine Ziege ist.

Anbei noch die Quick'n Dirty ausbesserung in der GameShow Klasse:
aus:


               int _result = PlayersChoise;
                while (_result == PlayersChoise)
                {
                    _result = Helpers.GetRandom(0, 2);
                    if (_result != PlayersChoise)
                    {
                        _doorResult = _doors[_result].OpenDoor();
                        ClosedDoors--;
                        if (switchDoor)
                        {
                            //gewählte auswahl Ändern
                            SwitchChoise();
                        }
                    }
                }

wird:


				int _result = PlayersChoise;
				while (_result == PlayersChoise)
				{
					_result = Helpers.GetRandom(0, 2);
					if (_result != PlayersChoise)
					{
						//Preis ist Ziege:
						if (_doors[_result].Type == Enums.Price.Goat)
						{
							_doorResult = _doors[_result].OpenDoor();

							ClosedDoors--;
							if (switchDoor)
							{
								//gewählte auswahl Ändern
								SwitchChoise();
							}
						}
						//keine Ziege
						else
						{
							_result = PlayersChoise;
						}
					}
				}

20.03.2012 - 10:50 Uhr

Hi,

vielleicht ist da schon mein Problem.
Meine Auffassung war, das der Moderator irgendeine Tür als erstes öffnet, mit Einschränkung das die vom Spieler gewählte Tür definitiv nicht geöffnet wird.
Der Moderator kann ja nicht definitiv eine Tür wählen/öffnen hinter der eine Ziege ist, denn wenn der Spieler eine Tür wählt hinter der eine Ziege ist.

Anbei mal die relevanten Methoden der GameShow sowie der Random Klasse:


		#region Methods
		public Enums.Price OpenDoor(bool switchDoor)
		{
			Enums.Price _doorResult = Enums.Price.None;
			//Soll das erste mal eine Tür geöffnet werden?
			if (ClosedDoors == 3)
			{
				int _result = PlayersChoise;
				while (_result == PlayersChoise)
				{
					_result = Helpers.GetRandom(0, 2);
					if (_result != PlayersChoise)
					{
						_doorResult = _doors[_result].OpenDoor();
						ClosedDoors--;
						if (switchDoor)
						{
							//gewählte auswahl Ändern
							SwitchChoise();
						}
					}
				}
			}
			//Es wurde schon (mindestens) eine Tür vor diesem Aufruf geöffnet
			else
			{
				foreach (Door _door in _doors)
				{
					if (!_door.Opend && _door.Number != PlayersChoise)
					{
						_doorResult = _door.OpenDoor();
						ClosedDoors--;
						return _doorResult;
					}
				}
			}
			return _doorResult;
		}
		public Enums.PlayResult Start(bool switchChoise)
		{
			Enums.Price _doorResult = Enums.Price.None;
			Enums.PlayResult _playResult = Enums.PlayResult.None;
			while (ClosedDoors > 1)
			{
				_doorResult = OpenDoor(switchChoise);
				if (_doorResult == Enums.Price.Car)
				{
					_playResult = Enums.PlayResult.Lost;
					break;
				}
				else if (_doorResult == Enums.Price.Goat)
				{
					_playResult = Enums.PlayResult.Won;
				}
				else
				{
					throw new Exception("Wrong DoorResult");
				}
			}
			return _playResult;
		}
		public void SwitchChoise()
		{
			foreach (Door _door in _doors)
			{
				if (!_door.Opend && _door.Number != PlayersChoise)
				{
					PlayersChoise = _door.Number;
					break;
				}
			}
		}
		#endregion

Random:


	public static class Helpers
	{
		private static Random _random = new Random();

		public static int GetRandom(int min, int max)
		{
			return _random.Next(min, max + 1);
		}

	}

Edit:
Der Code ist zwar nicht sonderlich Komplex, aber den Kompletten Code wollte ich nicht anhängen, der es meiner Meinung nach zu Unübersichtlich wird.
Hoffentlich reicht der gepostete Schnippsel.

20.03.2012 - 10:27 Uhr

Hi,

ich habe ein Problem welches ich nicht ganz "greifen" kann.
Soll heisen ich weis nicht an welcher Stelle das Problem liegt.

Ich möchte gerne das Ziegenproblem "nachstellen".
Kurze Beschreibung des Sachverhaltes:
Ein Spieler in einer Gameshow kann aus 1 von 3 Türen wählen.
Hinter 1 Tür ist ein Hauptpreis, hinter den anderen beiden sind Nieten (Ziegen).
Nach der Wahl des Spielers wird eine nicht vom Spieler gewählte Tür geöffnet.
Nach dem Öffnen fragt der Showmaster den Spieler ob er seine Wahl ändern möchte.
Jetz kommt der "Kernpunkt" des Ziegenproblems.
Kluge Köpfe haben herausgefunden, das wenn der Spieler nach dem Öffnen einer Tür seine Wahl auf die andere Tür setzt, die Warscheinlichkeit das der Spieler gewinnt höher wird, als wenn er seine Wahl beibehällt.

Um das ganze nachzustellen habe ich eine Klasse "GameShow" erstellt.
Diese enthällt eine Liste vom Typ "Door".
Eine Door hat ein "Price"-Enum-Property (Ziege oder Auto).
Dieser "Price" wird beim ersellen der Door automatisch auf "Ziege" gesetzt.

Beim erstllen einer GameShow wird die Liste mit 3 Türen gefüllt.
Dann wird per Zufall eine der 3 Türen auf "Pirce" : Auto gesetzt.

Die Auswahl des Spielers für welche Tür er sich entscheidet erfolgt ebenfals per Zufall (habe ich aber auch schon mit einem Konstanten Wert probiert).

Die Start-Methode der "GameShow" liefert mir eine Enum "PlayResult" (Lost/Won) zurück.
Dazu werden 2 Türen nacheinander "geöffnet".
Hat die "geöffnete" Tür den Price "Auto" wird das Spiel als Verloren gewertet, hat sie den Price "Ziege" und es wurden 2 Türen geöffnet, wird das Spiel als gewonnen gewertet, da hinter der letzten Tür der Hauptpreis liegen muss.

Um herauszufinden ob ich zum selben Ergebnis komme wie die o.g. klugen Köpfe habe ich 10000 GameShow Instanzen erzeugt und ohne einen Wechsel der Auswahl der Tür, für das sich der Spieler entschieden hat 2 Türen geöffnet.
Das ergebnis war, das ~1/3 aller Spiele gewonnen wurde.
Damit habe ich auch gerechnet.

Jetzt habe ich wieder 10000 GameShow Instanzen erzeugt und erneut 2 Türen geöffnet, allerdings habe ich nach dem öffnen der ersten Tür die Türwahl des Spielers geändert.
Das Ergebnis ist, das erneut nur 1/3 aller Speile gewonnen wurden, und nicht wie vermutet 2/3 aller Spiele.

Für die Wahl der zufälligen Tür des Spielers sowie hinter welcher Tür der Hauptpreis ist habe ich die Lösung aus folgendem Thread genutzt: [FAQ] Random.Next liefert eine Zeit lang die gleiche Zufallszahl - Warum? Wie geht es richtig? und das ganze noch in eine Statische Klasse gepackt um nicht jedes mal Instanzen erzeugen zu müssen.

Und genau jetzt komme ich nicht weiter.
Ich weis nicht an welchen Schrauben ich drehen muss um mein erwartetes Ergebnis zu erhalten.
Das Debugging bringt mich nicht wirklich weiter, da ich die Zufallszahlen nicht beeinflussen kann, auch ist der Code nicht sonderlich Komplex, sodas ich Fehler im Code ausschließen würde.
Die einzige Fehlerstelle scheint mir der Zufallsmechanismus zu sein, aber da der anscheinend korrekt ist weis ich nicht weiter.

Für einen Tipp / Hinweis wäre ich dankbar.

mfg

22.02.2012 - 15:49 Uhr

Hi,

ich habe ein Problem mit der Implementierung des MiniMax Algorithmus.
Im Netz gibt es zwar einen ganzen Sack voll Beschreibungen und eine Menge an Pseudo-Code, dessen Umsetzung eigenlich "nur" Fleisarbeit ist, aber ich komme trotzdem nicht weiter.

Ich habe als Implementierungsgrundlage folgenden "Pseudo-Code" genutzt: Der Minimax-Algorithmus
(In meiem Fall möchte ich den Algorithmus für ein Tic-Tac-Toe spiel nutzen und nicht für Schach)

Da ich keinen Integer als Rückgabewert der Funktion nutzen kann, da ich ja wissen muss welches Steinchen ich bewegen muss (bzw die "KI" / Computergegner), habe ich den Rückgabewert als "Spielstein" gewählt, der nach der Berechnung eine Kopie des Steiens ist, der besetzt werden soll.

Im Prinzip habe ich den Code nahezu 1:1 übersetzt.
Das ganze auch schon einige mal mit den verschiedenstetn Kombinationen der "ForEach"-Schleifen Position (vor der Abfrage auf maxDepth erreicht,...).

Aber nun zum wesentlichen:
Ich habe aus o.g. Gründen den Rückgabetyp in den Typ meiner "Spielsteine" umgeändert, und speichere Meine Bewertung des Spielbrettes in einer Int-Propertie des Steines.
Das Problem was ich habe ist, das wenn irgendwann mal ein guter Zug gefunden wurde, dieser Zug ausgeführt wird, egal was vorher passieren würde. Sprich, auch wenn der Gegenspieler (Ich) das Spiel gewonnen hat, aber der PC in 2 Zügen gewinnen würde, wird der berechnete vermeindliche Siegeszug als "Ziel" genommen und daruafhin gearbeitet.

Hier ein kleines Beispiel um das geschriebene zu verdeutlichen
(PC ist X) und an der Reihe eine Zug zu tätigen

|X|O| |
|!|O| |
|!|*| |

--> der PC würde seinen Stein auf eines der beiden "!" setzen, da wenn alle beiden "!" besetzt sind, er gewonnen hat.
Das ich aber meinen stein auf dem "*" Platziere und vorher gewinne wird dabei nicht berücksichtigt.

Da ich weder ausschließen kann ob das am Algorithmus liegt wollte ich fragen ob da vielleicht mal jemand nen Blick drauf werfen könnte.

Sollte ich einen generellen Fehler in meine Überlegung habe würde ich mich auch um einen helfenden Hinweis freuen.

Anbei mein genutzter Code:


public GameObject GetBestMove(int depth, int maxDepth, Enumerations.Type type, ref GameObject current)
{
	//X == KI		== "Enumeration.Type.Cross"	--> Maximieren --> default Referenz = int.Min
	//O == Mensch	== "Enumeration.Type.Circle"--> Minimieren --> default Referenz = int.Max
	int _xReference = Int32.MinValue + 1;
	int _oReference = Int32.MaxValue;

	List<GameObject> _freeBlocks = this.GameInstance.GetFreeObjects();

	if (depth == maxDepth || _freeBlocks.Count == 0)
	{
		//Bewertung des Spielfeldes durchführen
		//und bewertetes Object zurueck geben.
		GameObject _gameObject = new GameObject(current);
		_gameObject.Tag = this.GameInstance.Evaluate(current.Type);
		return _gameObject;
	}
	else
	{
		GameObject _retVal = null;

		foreach (GameObject _move in _freeBlocks)
		{
			//Zug durchfuehren ("silent" --> keine Events Triggern)
			_move.SetType(type, false);
			GameObject _dummy = new GameObject(_move);

			//Funktion mit "anderem" (inversem) Typ aufrufen und Ergebnis auswerten
			//Nur jeden "Halbzug" "depth" erhoehen
			Enumerations.Type _typeInvers = type == Enumerations.Type.Cross ? Enumerations.Type.Circle : Enumerations.Type.Cross;
			GameObject _current = new GameObject();
			if (type == Enumerations.Type.Circle)
			{
			_current = GetBestMove(depth, maxDepth, _typeInvers, ref _dummy);
			}
			else if (type == Enumerations.Type.Cross)
			{
				_current = GetBestMove(depth + 1, maxDepth, _typeInvers, ref _dummy);
			}


			//Zug auswerten
			if (_current.Type == Enumerations.Type.Cross)
			{
				if ((int)_current.Tag > _xReference)
				{
					_xReference = (int)_current.Tag;
					_retVal = new GameObject(_move);
				}
				else
				{
					//Zug auf jeden Fall ignorieren, da schlechter als Vorheriger Zug.
					GameObject _badMove = new GameObject(_move);
					_badMove.Tag = Int32.MinValue + 1;
					//_badMove.Position = _current.Position;
					//_badMove.SetType(_current.Type,false);
					_badMove.SetType(_move.Type, false);
					_retVal = _badMove;
				}
			}
			else if (_current.Type == Enumerations.Type.Circle)
			{
				if ((int)_current.Tag < _oReference)
				{
					_oReference = (int)_current.Tag;
					_retVal = new GameObject(_move);
				}
				else
				{
					GameObject _badMove = new GameObject(_move);
					_badMove.Tag = Int32.MaxValue ;
					//_badMove.Position = _current.Position;
					//_badMove.SetType(_current.Type, false);
					_badMove.SetType(_move.Type, false);
					_retVal = _badMove;
				}
			}

			//Zug zurueck setzen ("silent" --> keine Events Triggern)
			_move.SetType(Enumerations.Type.None, false);
		}
		return _retVal;
	}
}

Hinweise zum Code:
Die Funktion "GetFreeObjects()" liefert eine Liste von "GameObject" zurück, welche als "Type" Propertie den Wert "None" besitzen (--> Stein nicht besetzt)

Die Funktion "Evaluate()" bewertet die Situation auf dem Spielfeld.
Je mehr Steine zum Zeitpunkt des Funktionsaufrufes der gleichen "Partei" aneinender / nebeneinande liegen, desto Besser wird bewertet.
Besser bedeutet: für Spieler "Cross" --> größerer Wert, für Spieler "Circle" kleiner Wert (--> +80000 wäre gut für "Cross" und schlecht für "Circle").

Die Funktion "SetType(type,bool)" verändert die Type-Propertie des Spielsteines.
Der 2te Parameter ist für die Berechnung unwichtig.

20.02.2012 - 14:01 Uhr

Hi,

dazu hätte ich mal eine Frage / Anmerkung.
Wäre es nicht möglich dem Label/Anzeigeobjekt die Auswertung zu überlassen ob es einen Wert darstellen soll oder nicht?

Also z.B.: Eigene Klasse erstellen, die von "Label" erbt, und beim setzen des Textes mittels Stopwatch prüfen wann der Letzte Werte gesetzt wurde.
Wenn der Wert in diesem Fall <500 ist, dann weiterhin den alten Wert anzeigen, sonst aktualisieren und SW neustarten.

mfg

15.02.2012 - 01:03 Uhr

Hi,

In dem Context der Methode sollte dich fast nur der Inhalt der Methode interessieren und nicht, was alle darauffolgenden Methodenaufrufe alles vollziehen.
Du musst dich also in die Methode hineinversetzen und versuchen deine Aufgabe zu erfüllen. Dabei wird eine unter-methode aufgerufen(sich selbst) und die liefert "irgendein" ergebnis, mit dem man weiterarbeiten kann oder nicht.

Ich glaube genau das ist der springende Punkt an der Sache.
Dieses "irgendein" Ergebnis mit welchem weiter gearbeitet wird und die selben Parameter hat / liefert wie die "Aufrugmethode" ist das was mir Kopfzerbrechen bereitet.
Ich glaube / hoffe das das ganze eine Übungssache ist, die mit häufiger Wiederholung kommt und sich einprägt.
Auch das die Funktion aussagekräftiger sein sollte (auch wenn es nur der Funktionsname ist) ist ein guter Gedanke der mir weiterhelfen wird.

erstmal zur Beruhigung. Die wenigsten Leute verstehen Rekursion auf Anhieb.

Auch wenn es mir nicht weiterhilft ist es doch nett zu wissen das man sich selbst nicht zu dumm anställt 😃

Wenn sie dreimal aufgerufen wurde, dann ist die Situation genauso wie in dem Fall f -> g -> h. Gedanklich kannst du die Aufrufe einfach durchnummerieren, dann hast du nicht mehr das verwirrende f -> f -> f, sondern f1 -> f2 -> f3 und das ist fast so wie f -> g -> h. Auch was den Zustand angeht, den auch wenn sich eine Methode selbst aufruft, hat doch jeder Aufruf in der Kette seinen eigenen Satz von Parametern und lokalen Variablen.

Ich verstehe den Inhalt dessen was du geschrieben hast vollkommen, das wenn f->g->h und fgh --> f->f->f.
Nur mit dem letzen Teil habe ich so meine Probleme.
Wie oben schon geschrieben hoffe ich das sich dieses Problem durch häufige Anwendung hebt und der Punkt

Wenn man es erstmal verstanden hat, ist es dagegen super einfach, und man fragt sich, warum man jemals ein Problem damit hatte. relativ Zeitnah ergibt 😃

btw: Ich finde es etwas schade das der Thread Das Programmierspiel etwas eingeschlafen ist, denn für mich und vielleicht auch den ein oder anderen Einsteiger war das eine gut möglichkeit eigene Implementationen mit den "besten" geposteten Lösungen zu vergleich und dadurch zu profitieren.

Sollte der ein oder andere noch einen interesanten Gedankengang haben sich in die rekursive Implementation zu vertiefen kann er ihn ja gerne posten.

Vielen dank bisher.

mfg

14.02.2012 - 23:28 Uhr

Ich,

ich hätte eine programmiertechnische Frage.

Es geht um das Thema Rekursion.
Bisher konnte ich mich noch geschickt davor drücken eine Funktion rekursiv zu implementieren und habe immer den iterativen Weg genutzt.

Jetzt bin ich an einem Punkt der mir iterativ zu implementieren schwierig scheint und rekursiv eher sinnvoll umzusetzen ist.

Meine Frage ist:
Wie könnt ihr euch den rekursiven "Weg" einer Funktion vorstellen, bzw vor der Implemenierung "durchspielen" ob er auch so funktioniert wie er soll?
Ich möchte gerne den MinMax Algorithmus implemetieren und habe bei der 2-3 ten rekursion (bin mir nicht sicher ob der Begriff passt), also dem aufrufen der Funktion von sich selbst, Probleme mir vorzustellen welcher Zustand in welcher rekursion "aktuell" ist.

Da ich nicht anzweifle das sämtliche im Netz vorhandenen Pseudo-Codes und deren Umsetzug falsch sind, und mir eben nicht merken kann wann wo welcher Zustand vorhanden ist wollte ich um Tipps bitten die ihr vielleicht habt um eine rekursive Implemeniterung einer Funktion zu erleichtern.

P.s.: Es geht mir nicht um das Verständniss wie eine rekursive Funktion funktioniert, sondern darum sich den "Weg" der rekursiven Funktion besser vorzustellen.

mfg

03.02.2012 - 13:48 Uhr

Nachdem die Anwendung über ein Netlogon Script gestartet wird, kann ich sicher sein, dass beim starten eine funktionierende Netzwerkverbindung zum ActiveDirectory besteht.

Hi,

da du das anscheinden nicht geährleisten kannst solltest du vielleicht doch eine Abfrage einbauen die die Netzwerkverbindung vor Programmstart testet.
Sollte keine Netzwerkverbindung bestehen einfach wie du schon vorhast mitteils Timer warten.

03.02.2012 - 11:52 Uhr

Hi,

ich habe mehrere Klassen welche miteinander Kommunizieren.
Dabei habe ich eine Grundlegende Frage zur Kommunikation der Klassen untereinander.
Ich versuche gerade das "Design" / den Code relativ sauber zu implementieren und von Quick&Dirty Lösoung weg zu kommen.
Daher habe ich mich belesen und den Hinweis / Rat gelesen, das wenn Klasse_A Klasse_B kennt, Klasse_B Klasse_A NICHT kennen darf.
Macht für mich auch Sinn und habe ich so umgesetzt.

Jetzt habe ich folgende Konstelation:

Klasse_A hat eine Instanz von Klasse_B als Propertie.
Klasse_B führt eine Aktion aus und teilt Klasse_A mit das eine Aktion ausgeführt wurde (durch ein Event)
Dieses Event Abonniert Klasse_A und visulaisiert das Ergebnis.
Jetzt bedingt die Aktion abschließend eine Benutzereingabe (Erfasst in Klasse_A) ob die Aktion auch "Korrekt" war (das MUSS der Benutzer entscheiden, und kann nicht vom Programm verifiziert werden).
Da Klasse_A Klasse_B kennt kann ich einfach über Properties "kommunizieren".

Ist dies der "korrekte" / saubere Weg ?
Habe mir den Kopf zerbrochen ob es noch andere Möglichkeiten gibt, aber da Kommunikation mittels Events ausfällt, da Klasse_B Klasse_A NICHT kennt ist mir nichts weiter eingefallen.

mfg

01.02.2012 - 10:12 Uhr

Sorry, den FAQ habe ich übersehen.
Danke.

01.02.2012 - 09:58 Uhr

Hi,

ich habe eine Klasse die Events bei verschiedenen Rahmenbedingungen triggert.
Jetzt kann es sein das die Rahmenbedingungen zutreffen ich aber dennoch nicht möchte das die Events getriggert werden.

Bisher konnte ich mir damit weiterhelfen das ich die Relevanten Eventhandler deregestriert habe, dann die "Aktion" ausgeführt" habe und die Eventhandler anschließend wieder regestriert habe.

Man könnte doch aber auch ein Propertie "SupressEvents" bzw "TriggerEvents" in der Klasse erstellen und vor dem Triggern das jeweilige Propertie abfragen.

Jetzt zu meiner Frage: welche Methode ist zu bevorzugen, bzw gibt es eine "bessere" als die von mir genannten (Eventhandler vs. Propertie) ?

mfg

16.01.2012 - 17:21 Uhr

Hi,

ich habe ein Problem mit folgendem Verhalten:
Ich fülle eine Liste mit bestimmten Objekten.
Anschliessend möchte ich mit der Contains Mehtode der List-Klasse feststellen ob sich ein bestimmtes Objekt in der Liste befindet.
Obwohl ich sicher bin das ein passendes Objekt in der Liste enthalten ist (durch Debugging überprüft) liefert die Methode "false" zurück.
Um sicherzustellen das es nicht am restlichen Code liegt habe ich ein kleines Testprojekt erstellt, dort zeigt sich allerdings das selbe Verhalten.

Anbei mal meine Testklasse mit entsprechndem Aufruf.

Testklasse / Objekt:


namespace CustomObject
{
	public class MyObject
	{
		#region Properties

		public int Wert1
		{
			get;
			set;
		}
		public string Wert2
		{
			get;
			set;
		} 
		
		#endregion

		#region Constructor

		public MyObject()
		{
		}
		public MyObject(int Wert1, string Wert2)
		{
			this.Wert1 = Wert1;
			this.Wert2 = Wert2;
		} 
		#endregion

		#region Operators

		public static bool operator ==(MyObject Object1, MyObject Object2)
		{
			if ( Object1.Wert1 == Object2.Wert1 && Object1.Wert2 == Object2.Wert2 )
			{
				return true;
			}
			return false;
		}
		public static bool operator !=(MyObject Object1, MyObject Object2)
		{
			if ( Object1.Wert1 != Object2.Wert1 || Object1.Wert2 != Object2.Wert2 )
			{
				return true;
			}
			return false;
		}

		#endregion

	}
}

Der Aufruf, der "false" zurück liefert obwohl ich "true" erwarten würde:


using System;
using System.Collections.Generic;
using System.Windows.Forms;
using CustomObject;


namespace Test_ListContains
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			List<MyObject> _list = new List<MyObject>();
			_list.Add(new MyObject(1, "TEST1"));
			_list.Add(new MyObject(2, "TEST2"));
			_list.Add(new MyObject(3, "TEST3"));
			_list.Add(new MyObject(4, "TEST4"));

			MyObject _obj = new MyObject(2, "TEST2");

			MessageBox.Show(_list.Contains(_obj).ToString());

		}
	}
}

Es spielt anscheinend auch keine Rolle welche Datentypen das Objekt bestitzt, da in meiner Eigentlichen Klasse das entsprechende Objekt 2 Byte Werte besitzt.

Habe ich irgend etwas übersehen ?

mfg

12.01.2012 - 09:50 Uhr

Hallo,

ich schreibe gerade an einer eigenen List<T> Klasse.
Ich habe eine Funktion "Copy" erstellt.
Diese ist wie folgt implementiert:


public ExtendedList<T> Copy(ExtendedList<T> Orginal) {
	ExtendedList<T> _internal = new ExtendedList<T>();
	foreach (T Item in Orginal) {
		_internal.Add(Item);
	}
	return _internal;
}

Da mir folgender Aufruf der Methode nicht gefällt


ExtendedList<int> _orginal = new ExtendedList<int>();
ExtendedList<int> _copy = new ExtendedList<int>();
_orginal.Add(1);
_orginal.Add(2);
_copy = _orginal.Copy(_orginal);

woltle ich eine Erweiterungsmehtode erstellen, welche komfortabler wäre.
Allerdings erhalte ich folgende Compilerfehlermeldung:> Fehlermeldung:

Erweiterungsmethoden müssen in einer nicht generischen statischen Klasse definiert werden.

Heist das, das es keine Möglichkeit gibt Erweituerngsmethoden für nicht Generische Klassen zu ersetllen?
Oder gibt es irgend eine Möglichkeit dies doch zu tun?

mfg

31.12.2011 - 16:15 Uhr

Hallo zusammen,

besten Dank für die Antworten.
Ich werde mich die Tage an die Umsetzung machen und Posten sobald ich fertig bin.
Das die Event-Triggernde Klasse mit der Bearbeitung wartet bis das Event "abgearbeitet" ist, war mir neu.
Danke für den Hinweis.

Das es dadurch zu erheblichem Zeitverlust kommt war mir klar. Da es nur als Gimmick dienen soll ist das auch in Ordnung.

Danke auch an winSharp93 für eine Mögliche Umsetzungsvariante.

mfg

30.12.2011 - 23:52 Uhr

Hi,

ein Timer alle 250ms wäre zu ungenau, da sich in der Zeit zu viel ändert.
Im Anhand mal ein Bild eines Beispiels.
Das Linke Bild zeigt den Ursprungszustand. "Start" is oben links, das "Ziel" ist unten rechts. Das hell eingezeichnete ist der gefundene Pfad.
Die Zeit um den Weg dorthin zu finden hat (mittels StopWatch ermittelt) 1407ms gebraucht.

Gibt es eine "elgante" Möglichkeit Events zwischen 2Klassen hin und her zu senden, ala "Status hat sich geändert" --> Algorithmus pausieren --> Status dargestellen ---> Event senden "Status gezeichnet" --> daraufhin Algorithmus fortsetzen, ...

Damit würde ich jede Änderung mitbekommen und zeichnen können.

Ist es "üblich" so etwas zu machen, bzw kann es evtl zu Problemen dabei kommen?

mfg

30.12.2011 - 18:20 Uhr

Hi,

ich habe einen Algorithmus zur Wegfindung implementiert, welcher auch soweit funktioniert.
Jetzt möchte ich das ganze als Gimmick noch etwas grafisch auffrischen, und während der Wegfindung den Zustand jedes Knoten farblich hervorheben, sollte sich dieser ändern.

Die Implementation ist folgendermassen aufgebaut:
Das Feld, was durchsucht werden soll besteht aus einer 2-Dimensionalen "matrix", aus Knotenpunkten. Diese Knoten haben eine Enum-Propertie (Nicht Untersucht,Untersucht, Untersucht und besten Weg gefunden).Dieses Propertie möchte ich Farblich nach außen "hervorheben".

Visualisiert wird der Algorithmus von einer "Visualizer" Klasse (erbt von Panel) , welche die Matrix mit den Wänden,Freien, Start und Ziel - Knoten in Form von Panels darstellt.

Die Frage dich ich mit stelle ist, wie die Kommunikation zwischen den beiden Klassen am besetn realisieren, bzw Synchronisieren ?

Ich könnte in der Algorithmus Klasse ein Event feuern wenn sich der Zustand eines Knoten ändert, und dieses Event dann in der "Visualizer"-Klasse registrieren und das Entsprechende Panel einfärben. Das Problem ist, das der Algorithmus deutlich schneller einen Weg findet als der Visualizer ein Panel einfärbt. Gibt es eine möglichkeit die beiden Klassen zu synchronisieren?
Das das Einfluss auf die Zeit der Wegfindung hat ist mir klar, aber das ganze soll eine Gimmick sein.

mfg

28.12.2011 - 17:28 Uhr

Auszug aus der MSDN zum Stichwort "Implements"

Gibt eine oder mehrere Schnittstellen oder Schnittstellenmember an, die in der umgebenden Klassen- oder Strukturdefinition implementiert werden müssen.

Projekt--> Verweis Hinzufügen --> Projekte --> "dein Projekt" auswählen.

Auserdem: Dim xxx as YYYY = new YYYY() ist VB und nicht C#.

21.12.2011 - 21:31 Uhr

Hallo,

ich beschäftige mich gerade etwas mit der Pfadberechnung aufgrund folgendes Artikels / Tutorials: A* Pathfindung für Anfänger

Ich habe mehr oder weniger erfolgreich die Pfad bestimmung implementiert, und bin auf einen Fehler in meinem Code gestossen.
Das "Ergebnis" der berechnung sieht man auf folgendem Bild (Oben Links Start, Unten Rechts Ziel): siehe Anhang

Die Relevante Stelle im Code zum Setzen des "Parents", also des Vorgänger-Knoten sieht folgendermassen aus (der "Parent" wird benötigt um den letztendlichen Pfad vom Ziel zum Start (rückwärts) zu ermitteln)


		void CheckParent(ExtendedPanel Current, ref List<ExtendedPanel> Children) {
			foreach ( ExtendedPanel child in Children ) {
				if ( child.G < GetG(Current, child) ) {
					child.G = GetG(Current, child);
					child.Parent = Current;
				}
			}
		}

Jetzt habe ich o.g. Code durch folgenden Code ersetzt:


		void CheckParent(ExtendedPanel Current, ref List<ExtendedPanel> Children) {
			for ( int i = 0 ; i < Children.Count - 1 ; i++ ) {
				if ( Children[i].G < GetG(Current, Children[i]) ) {
					Children[i].G = GetG(Current, Children[i]);
					Children[i].Parent = Current;
				}
			}
		}

Also, ist lediglich der Schleifenkörper von ForEach zu For geändert worden.
Allerdings erhalte ich ein anderes Bild, bzw einen anderen errechneten Pfad.
(Ausgangssituation ist die selbe wie oben): siehe Anhang

Die gepostete Methode wird nur 1 einziges mal aufgerufen.
Unabhängig von meinem anderen Code sollte doch wenn NUR der Schleifenkörper ausgetauscht wird, aber die Logik in der Schleife die selbe bleibt auch immer mein Ergebnis das selbe bleiben oder?

mfg

P.S.: Im Anhang die ein Bild mit welches (oben) das ForEach -Ergebnis zeigt und unten das For - Ergebnis.

15.12.2011 - 22:16 Uhr

Hi,

ich kann dir zwar nicht direkt helfen, aber ich hätte einen Tip zur besseren Lesbarkeit deines Codes.
Dieser Teil führt genau dasselbe aus wie dein code, aber ich pesönlich kann folgenden code "besser" lesen:


		private bool checkImage(Bitmap bmp1, Bitmap bmp2) {
			if ( bmp1 == null || bmp2 == null )
				return false;

			if(bmp1.Width != bmp2.Width || bmp1.Height != bmp2.Height)
				return false;

			for ( int x = 0 ; x < bmp1.Width ; x++ ) {
				for ( int y = 0 ; y < bmp1.Height ; y++ ) {
					if ( bmp1.GetPixel(x, y) != bmp2.GetPixel(x, y) ) {
						return false;
					}
				}
			}
			return true;
		}

Vielleicht würde es etwashelfen wenn du die Zeilennumern mit angibst.
In der Fehlermeldung sind diese zwar geschrieben, aber im Forums-Code erscheinen diese selbstverständlich nicht.

mfg

15.12.2011 - 13:01 Uhr

Hallo Th69,

das auslagern der Bearbung in einen Thread habe ich vorgenommen nachdem meine ursprüngliche Lösung (das ermitteln des Senders über das MouseMove Event) nicht funktionierte.

Weiterhin viel mir keine Möglichkeit eingefallen herauszubekommen ob der cursor Gerade über einem Objekt (Panel) ist als einen Thread solange laufen zu lassen bis die Maustaste losgelassen wird und im Thread die von dir gepostete Variante "Control.Bounds.Location(...)" zu nutzen um eine "Kollision" zu ermitteln.

14.12.2011 - 21:17 Uhr

Hallo herbivore,

ich wäre mit der Lösung durch erkennen der Kontrols im jeweiligen MouseMove Event auch zufriedener, allerdings funktioniert das nicht (Siehe Startpost).

Ich habe mir das MouseMove Event der erstllen Panels abonniert und wollte über den Sender prüfen welches Panel das Event feuert, allerdings feuert solange eine Maustaste gedrükt ist immer das Panel das Event auf welchem das "MouseDown" durchgeführt wurde, auch wenn die Maus vom ursprünglichem Panel weg und auf ein anderes Panel bewegt wurde.

mfg

14.12.2011 - 15:46 Uhr

Hi,

besten dank, damit hats funktioniert.

Ich habe beim MouseDown ein globales Bit gesetzt sowie einen Thread gestartet welcher nachfoglende Routine solange abarbeitet wie Die Maustaste gedrückt wird.

  • Ich gehe jedes Meiner Panels in einer schleife durch, "invoke" es und prüfe im Delegaten ob das Panel vom Cursor berührt wird. Wenn ja wird die Hintergrundfarbe geändert.

-->


    delegate void CheckPanel_Delegate(Panel panel);
    void CheckPanel(Panel panel) {

    if (panel.Bounds.Contains((PointToClient(Cursor.Position)))) {
        panel.BackColor = BorderColor;
    }

    }

....
......

    for (int i = 0 ; i < panels.Count - 1 ; i++) { 
        CheckPanel_Delegate c = new CheckPanel_Delegate(CheckPanel);
        panels[i].Invoke(c, new object[] { temp[i] });
    }

mfg

14.12.2011 - 11:40 Uhr

Hallo,

ich habe eine Windows Forms Anwendung, welcher zu Laufzeit Panels hinzugefügt werden.
Das ganze soll optisch eine Art "Grid" wiederspiegeln.

Jetzt möchte ich die Panels durch einen Mausklick einfärben, was auch soweit funktioniert.

Was ich nun realisieren möchte ist, das bei gedrückter Maustaste alle vom Mauscursor überfahrenen Panels eingefärt werden.

Was ich mir überlegt habe ist das ich im "MouseMove" - Event der Panels abfrage ob Maustaste gedrückt und Entsprechend reagiere ( --> der Sender des Events sollte das Panel sein) , allerdings liefert das "MouseMove" Event solange den gleichen Sender, bzw wird vom gleichen Sender gefeuert wie eine Maustaste gedrückt wird, also erfahre ich duch dieses Event nicht über welche Panels der Mauszeiger gefahren ist.
Das gleiche habe ich mit den Events "MouseHover" und "MouseEnter" festgestellt.

Kann mir jemand weiter helfen?

mfg

24.11.2011 - 14:48 Uhr

Hi,

Ob es irgendwann mal vorkommt das ich>1000 Controls ertsellen muss weis ich nicht, nur habe ich meine Import/Export Funktion getestet und dabei eben festgesetllt das es ab einer gewissen Anzahl an Objekten zu dem beschriebenen Fehler kommt.

Das erstllen der Controls aus dem XML File sollte eigentlich vom Programmierttechnischen Gesichtspunkt hoffentlich "sauber" gelöst worden sein. Fals nicht würde ich das abändern, sofern mir jemand sagen würde das falsch ist.

Zum Thema Daten anstatt Controls speichern:
Mein Programm soll später mal ein kleiner "Editor" sein, d.h. Ich muss verschiedene Controls ersellen, deren Properties ändern/erstellen,.... und unter andem auch dieses Controls "frei beweglich" auf meiner Form verschieben.
Daher die Grafische Darstellung der Eigenschaften über das UserControl.

Weiterhin speichere ich ja "nur" die Daten der Controls ab, indem ich mir jedes (für mich relevante) Propertie abspeichere, und beim "laden" des Controls dieses gespeicherte Properies einer neuen Instanz zuweise.

mfg