Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

CSharp Objekte !zufällig! sichtbar machen

Frage Entwicklung C und C++

Mitglied: stargazer

stargazer (Level 1) - Jetzt verbinden

16.07.2011 um 19:43 Uhr, 5348 Aufrufe, 20 Kommentare

Hallo zusammen!

Ich habe mal wieder ein kleines Problemchen. Ich möchte diesmal mit C# eine Tix-Clock programmiren. Dazu habe ich insgesamt vier "Spalten" mit verschiedener Anzahl Blöcken erstellt (1x3, 3x3, 2x3, 3x3).
In jedem Block befindet sich eine Grafik, die bei Programmstart unsichtbar ist. Sobald das Programm gestartet wird wird ein Timer ausgelöst, der im Sekundentakt die Uhrzeit ausliest und dann die Uhrzeit ausgeben soll.
So weit so gut, aber leider klappt das alles noch nicht so ganz. Bei der Tix-Clock wird jede Sekunde auch ein neues, zufälliges "Muster" in jedem Block ausgegeben, welches natürlich auf der aktuellen Uhrzeit basiert.
Ich hab also zuerst versucht mittels Bedingungssätzen jedes mal ein neues Muster zu erzeugen, doch da habe ich schon nach kürzester Zeit den überblick verloren.
Meine Frage also: kann ich mehrere zufällige Objekte sichtbar machen, ohne eine gigantische if-Struktur aufzubauen?

Auslesen der Uhrzeit:


DateTime currentDate = DateTime.Now;
int dtHour = currentDate.Hour;
int dtMinute = currentDate.Minute;
int dtSecond = currentDate.Second;

Da ich noch keine zufälligen Strings generieren kann hab ich zuerst angefangen random Zahlen auszugeben.

private int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}

Ich habe den Grafiken jeweils eindeutige Namen zugeteilt (daher die 4. Grafik in der 2. Spalte heißt z.B. Image2x4). Jetzt hatte ich mir erhofft über die zufällige Zahl direkt den Namen generieren zu können (was aber nicht klappte - hier nochmal der code).

String ch1 = new String;
int num0 = RandomNumber(1, 9);
ch1 = "Image2x" + num0;
if (dtHour == 15) {
if (num0 == 1) {
ch1.Visibility = Vilibility.Visible; }}


So einfach war es nunmal leider nicht. Aber ich denke irgendwas derartiges muss es doch geben, oder irgendeine Alternative?
Falls ihr eine Idee habt, lasst mich es bitte wissen!

Schöne Grüße

stargazer
Mitglied: dog
16.07.2011 um 20:41 Uhr
ch1 = "Image2x" + num0;

In einer statischen Programmiersprache wie C# wird das niemals gehen.

Schau dir mal mehrdimensionale Arrays an.
Bitte warten ..
Mitglied: stargazer
16.07.2011 um 21:04 Uhr
Alles klar, ich schau mal^^
Ach ja, würde es evtl mehr Sinn machen, die Position der Einzelnen Images zu Randomisieren?

Stargazer
Bitte warten ..
Mitglied: dog
16.07.2011 um 21:28 Uhr
Ach ja, würde es evtl mehr Sinn machen, die Position der Einzelnen Images zu Randomisieren?

Wenn du es dir absichtlich kompliziert machen willst, ja.
Bitte warten ..
Mitglied: Jenna86
17.07.2011 um 11:14 Uhr
Hi stargazer,

Also ich bin mir nicht sicher, ob ich dich richtig verstanden habe.

Aber so ein "zufälliges" ändern der Sichtbarkeit von verschiedenen Objekten würde ich schon über ein Array machen, in dem sich die Objekte befinden.
Der Index ist dann zufällig und dadurch kommst du immer wieder an eins deiner Objekte ran.
Dann würde ich halt die Sichtbarkeit des Objektes auf true setzen und vor dem jeweiligen setzen auf true jede Sekunde hingehen und vorher komplett alles auf "false" setzen um den Ausgangszustand zurückzubekommen.

Also nochmal kurzfassung:

Jeder Spalte ein Array aus Blöcken zuweisen.
Alle Blöcke invisible setzen
Arrayindex per Zufall auswählen lassen und auf visible setzen ( du kannst natürlich auch zufällig viele Blöcke sichtbar machen über eine zweite Zufallszahl. Also eine Zufallszahl jeweils für den Index und eine Zufallszahl für die Anzahl der Durchgänge, in denen du einen zufälligen Block sichtbar machst )
Und das machst du einfach durchgehend, solltest aber vor jedem neuen Sichtbarmachen eben vorher alles "resetten".

Ich hoffe ich habe das Problem so halbwegs verstanden.

Wie hast du den Timer hingebogen? Du kannst die interne Klasse Timer benutzen, die dann in einem festgelegten Intervall ein Event "Tick" auslöst. So kannst du z.B. den Intervall auf 1000ms setzen und dann jedesmal deine Logik ausführen lassen.

Grüße
Jens
Bitte warten ..
Mitglied: stargazer
17.07.2011 um 15:15 Uhr
Das mit dem Timer ist bereits eingerichtet:

private void TimerTicker(Object ReadoutTimer, EventArgs myEventArgs)
{
DateTime currentDate = DateTime.Now;
int dtHour = currentDate.Hour;
int dtMinute = currentDate.Minute;
int dtSecond = currentDate.Second;
Image1x1.Visibility = Visibility.Hidden;
Image1x2.Visibility = Visibility.Hidden;
Image1x3.Visibility = Visibility.Hidden;
Image2x1.Visibility = Visibility.Hidden;
Image2x2.Visibility = Visibility.Hidden;
...

und

private void Window_Loaded(object sender, RoutedEventArgs e)
{
var ReadoutTimer = new Timer();
ReadoutTimer.Interval = 1000;
ReadoutTimer.Enabled = true;
ReadoutTimer.Tick += new EventHandler(TimerTicker);
}

Ich gucke zur Zeit nach den arreys, aber hab deren Funktionsweise noch nicht so ganz verstanden. Ich werds einfach mal versuchen, wenn Fragen aufkommen meld ich mich nochmal :D


Vielen Dank für die Hilfe!


stargazer
Bitte warten ..
Mitglied: Jenna86
17.07.2011 um 17:34 Uhr
Okay, alles klar. Ich glaube ich habe grad etwas Langeweile und hab mal nach der Uhr gegooglet.

Ich glaub ich probier das auchmal fix zu implementieren, aber ich werds denke ich statt mit irgendwelchen Buttons oder ähnlichen Dingen direkt mit nem Panel machen, in welches ich zeichne. Falls ich da heute Abend noch was mache und zu was komme, lass ich dich wissen, wie ichs gelöst habe.

Grüße

EDIT (ein paar Denkanstöße):

Anstelle von blanken int-Werten benutze ich lieber Enums.
01.
        enum Pos 
02.
03.
            HourFirst, 
04.
            HourLast, 
05.
            MinuteFirst, 
06.
            MinuteLast 
07.
        }
Hiermit bekomme ich die Anzahl an Punkten, die im jeweiligen Feld dargestellt werden soll.
01.
        private int getPointsToDraw(int charOfTime) 
02.
03.
            int pointsToDraw = 0; 
04.
 
05.
            switch (charOfTime) 
06.
07.
                case (int)Pos.HourFirst: 
08.
                        pointsToDraw = DateTime.Now.Hour / 10; 
09.
                    break; 
10.
                case (int)Pos.HourLast: 
11.
                        pointsToDraw = DateTime.Now.Hour % 10; 
12.
                    break; 
13.
                case (int)Pos.MinuteFirst: 
14.
                    pointsToDraw = DateTime.Now.Minute / 10; 
15.
                    break; 
16.
                case (int)Pos.MinuteLast: 
17.
                    pointsToDraw = DateTime.Now.Minute % 10; 
18.
                    break; 
19.
20.
            return pointsToDraw; 
21.
        }
Die Methode liefert mir eine ArrayListe, welche die Position für das jeweilige Rechteck liefert
01.
        private ArrayList randomizePositions(int numberofpositions, int numberofshownrecs) 
02.
03.
            Random rand = new Random(DateTime.Now.Millisecond); 
04.
            ArrayList positions = new ArrayList(); 
05.
            int tmp = 0; 
06.
 
07.
            //get random position(s) for this field 
08.
            for (int i = 0; i < numberofshownrecs; i++) 
09.
10.
                while (true) 
11.
12.
                    tmp = rand.Next(0, numberofpositions); 
13.
                    if (!positions.Contains(tmp)) 
14.
15.
                        positions.Add(tmp); 
16.
                        break; 
17.
18.
19.
20.
 
21.
            return positions; 
22.
        }
Und schlussendlich die Zeichenmethode. Über das bisschen Mathe um den Index fürs Zeichnen zu berechnen könntest du statt nen Index für die Zeichenmethode auch nen Index für nen Array benutzen.
01.
        private void draw() 
02.
03.
            ArrayList positions = new ArrayList(); 
04.
 
05.
            //fields for first char of hours ( 1*3 field ) 
06.
            positions = randomizePositions(3, getPointsToDraw((int)Pos.HourFirst)); 
07.
            for (int i = 0; i < positions.Count; i++) 
08.
09.
                g.FillRectangle(Brushes.Red, new Rectangle(_HOURSPOS_X, 
10.
                    (int)positions[i] *(_HEIGHT+_PLACEBETWEENITEMS)+_HOURSPOS_Y,  
11.
                    _WIDTH,  
12.
                    _HEIGHT)); 
13.
14.
 
15.
            //fields for the second char ( 3*3 field ) 
16.
            positions = randomizePositions(9, getPointsToDraw((int)Pos.HourLast)); 
17.
            for (int i = 0; i < positions.Count; i++) 
18.
19.
                g.FillRectangle(Brushes.Orange,  
20.
                    new Rectangle(_HOURSPOS_X + (_WIDTH + _PLACEBETWEENITEMS) + ((int)positions[i] / 3 * (_WIDTH + _PLACEBETWEENITEMS)), 
21.
                    (int)positions[i] % 3 * (_HEIGHT + _PLACEBETWEENITEMS) + _HOURSPOS_Y,  
22.
                    _WIDTH,  
23.
                    _HEIGHT 
24.
                    )); 
25.
26.
 
27.
            //fields for the third char ( 2*3 field ) 
28.
            positions = randomizePositions(6, getPointsToDraw((int)Pos.MinuteFirst)); 
29.
            for (int i = 0; i < positions.Count; i++) 
30.
31.
                g.FillRectangle(Brushes.Black, 
32.
                    new Rectangle(_HOURSPOS_X + 4 * (_WIDTH + _PLACEBETWEENITEMS) + ((int)positions[i] / 3 * (_WIDTH + _PLACEBETWEENITEMS)), 
33.
                    (int)positions[i] % 3 * (_HEIGHT + _PLACEBETWEENITEMS) + _HOURSPOS_Y, 
34.
                    _WIDTH, 
35.
                    _HEIGHT 
36.
                    )); 
37.
38.
 
39.
            //fields for the forth char ( 3*3 field ) 
40.
            positions = randomizePositions(9, getPointsToDraw((int)Pos.MinuteLast)); 
41.
            for (int i = 0; i < positions.Count; i++) 
42.
43.
                g.FillRectangle(Brushes.Blue, 
44.
                    new Rectangle(_HOURSPOS_X + 6 * (_WIDTH + _PLACEBETWEENITEMS) + ((int)positions[i] / 3 * (_WIDTH + _PLACEBETWEENITEMS)), 
45.
                    (int)positions[i] % 3 * (_HEIGHT + _PLACEBETWEENITEMS) + _HOURSPOS_Y, 
46.
                    _WIDTH, 
47.
                    _HEIGHT 
48.
                    )); 
49.
            }    
50.
        }
Ich denke, dass dir das schonmal deutlich weiterhelfen sollte.
Falls du noch Rückfragen hast, dann lass michs wissen.

Grüße
Jens
Bitte warten ..
Mitglied: Jenna86
17.07.2011 um 20:24 Uhr
Ich habe hier mal mein Beispiel fix als *.exe hochgeladen, damit du dir visuell vorstellen kannst, was da passiert:

http://www.file-upload.net/download-3592987/TixClock.exe.html

Grüße
Bitte warten ..
Mitglied: Jenna86
17.07.2011 um 22:52 Uhr
Zitat von stargazer:
Ich gucke zur Zeit nach den arreys, aber hab deren Funktionsweise noch nicht so ganz verstanden. Ich werds einfach mal versuchen,
wenn Fragen aufkommen meld ich mich nochmal :D


Vielen Dank für die Hilfe!


stargazer

Heyho, also schon wieder ich.
Das hat mir jetzt keine Ruhe gelassen xD
Ich zeig dir nochmal eine Möglichkeit, wie man das mit z.B. PictureBoxen machen könnte.

- Zu allererst erstellst du dir ( am Besten automatisiert ) ein Array mit neuen PictureBoxen.
Da dich das aber eventuell überfordert hab ich mir tatsächlich mal die Arbeit gemacht das alles zu tippen
- anschließend werden die Positionen wie schon bekannt per Zufall gesetzt ( wie im "alten" Beispiel )
- die draw() Methode oder wie ich sie nannte musst du nun etwas anpassen. Dazu zeige ich dir fix noch ein paar Codefetzen.

Die im Designer erstellten PictureBox(en) in die arrays füllen ( ein Array pro Box )
01.
        private void initPictureBoxArrays() 
02.
03.
            hour1 = new PictureBox[3]; 
04.
            hour1[0] = pictureBox1; 
05.
            hour1[1] = pictureBox2; 
06.
            hour1[2] = pictureBox3; 
07.
 
08.
            hour2 = new PictureBox[9]; 
09.
            hour2[0] = pictureBox4; 
10.
            hour2[1] = pictureBox5; 
11.
            hour2[2] = pictureBox6; 
12.
            hour2[3] = pictureBox7; 
13.
            hour2[4] = pictureBox8; 
14.
            hour2[5] = pictureBox9; 
15.
            hour2[6] = pictureBox10; 
16.
            hour2[7] = pictureBox11; 
17.
            hour2[8] = pictureBox12; 
18.
 
19.
            min1 = new PictureBox[6]; 
20.
            min1[0] = pictureBox13; 
21.
            min1[1] = pictureBox14; 
22.
            min1[2] = pictureBox15; 
23.
            min1[3] = pictureBox16; 
24.
            min1[4] = pictureBox17; 
25.
            min1[5] = pictureBox18; 
26.
 
27.
            min2 = new PictureBox[9]; 
28.
            min2[0] = pictureBox19; 
29.
            min2[1] = pictureBox20; 
30.
            min2[2] = pictureBox21; 
31.
            min2[3] = pictureBox22; 
32.
            min2[4] = pictureBox23; 
33.
            min2[5] = pictureBox24; 
34.
            min2[6] = pictureBox25; 
35.
            min2[7] = pictureBox26; 
36.
            min2[8] = pictureBox27; 
37.
        }
Die resetView() Methode, die dir vor jedem neuen Schritt die default-Ansicht wieder herstellt
Er nimmt sich einfach alle PictureBox-Objekte, die in der Form existieren. Das erspart einiges an Arbeit im Vergleich zum manellen Setzen

01.
        private void resetView() 
02.
03.
            foreach (PictureBox pictb in this.Controls.OfType<PictureBox>()) 
04.
05.
                pictb.Image = imageDefault; 
06.
07.
        }
Und nun die neue updateView()-Methode ( vorher draw-Methode ). Hier werden nun die Zufallszahlen nichtmehr zur Positionsberechnung ( wie oben ) verwendet, sondern sie geben den Index der PictureBox an, die verändert werden soll
01.
        private void updateView() 
02.
03.
            resetView(); 
04.
            ArrayList positions = new ArrayList(); 
05.
            //box1 
06.
            positions = randomizePositions(3,getPointsToDraw((int)Pos.HourFirst)); 
07.
            for (int i = 0; i < positions.Count; i++) 
08.
09.
                hour1[(int)positions[i]].Image = imageSet; 
10.
11.
            //box2 
12.
            positions = randomizePositions(9, getPointsToDraw((int)Pos.HourLast)); 
13.
            for (int i = 0; i < positions.Count; i++) 
14.
15.
                hour2[(int)positions[i]].Image = imageSet; 
16.
17.
            //box3 
18.
            positions = randomizePositions(6, getPointsToDraw((int)Pos.MinuteFirst)); 
19.
            for (int i = 0; i < positions.Count; i++) 
20.
21.
                min1[(int)positions[i]].Image = imageSet; 
22.
23.
            //box4 
24.
            positions = randomizePositions(9, getPointsToDraw((int)Pos.MinuteLast)); 
25.
            for (int i = 0; i < positions.Count; i++) 
26.
27.
                min2[(int)positions[i]].Image = imageSet; 
28.
            }  
29.
        }
Was für dich in dem Zusammenhang vielleicht noch interessant ist wäre wie man ne Bitmap benutzt um sie hier zu benutzen.
Ich habe dazu das Bild ( bmp ) als Ressource eingebunden ( Dann wird sie, wenn gewünscht in die *.exe gepackt und du hast nur eine Datei ).
-> Rechtsklick auf das Projekt -> Eigenschaften -> Ressourcen -> Hinzufügen -> Aus Datei oder so

Anschließend kannst du diese Ressourcen im Code nutzen über "Resources.XXX". Dafür ist es sinnvoll über die using-Direktive die Properties einzubinden. "using PROJEKTNAME.Properties;"

Jetzt kannst du ein Image zum Beispiel so initialisieren:

01.
        Image imageSet; 
02.
        Image imageDefault; 
03.
 
04.
        public TixWithImages() 
05.
06.
            InitializeComponent(); 
07.
            imageSet = Resources.set;                            <<<<<<-------- 
08.
            imageDefault = Resources._default;            <<<<<<-------- 
09.
            initPictureBoxArrays(); 
10.
            resetView(); 
11.
            timer.Start(); 
12.
        }
Sohoo, scheiße, wenn das Wetter so schlecht ist, dass man mit SAT keinen Empfang hat und dann nach "Beschäftigung" sucht :D

Sorry, falls das schon zu ausführlich war, letzten Endes hast du ja jetzt ein komplett lauffähiges Programm.

Bitteschön,
"Jenna"

EDIT:

Du kannst natürlich statt da nen Image jedesmal zu setzen auch hingehen und die Sichtbarkeit ändern. Also du könntest auch generell überall nur ein Bild anzeigen lassen und dann statt die Bilder zu ändern das Element eben unsichtbar und sichtbar machen. Das wäre ja dann g enau das, was du eigentlich wolltest denke ich mal.
Bitte warten ..
Mitglied: stargazer
17.07.2011 um 23:23 Uhr
Hi Jenna!

Wow. Erstmal vielen Dank für diesen Code, werds gleich mal ausprobieren und versuchen zu verstehen :D

- Zu allererst erstellst du dir ( am Besten automatisiert ) ein Array mit neuen PictureBoxen.
Da dich das aber eventuell überfordert hab ich mir tatsächlich mal die Arbeit gemacht das alles zu tippen ^^

Leider wahr. Fange demnächst mit meiner MATSE-Ausbildung an und hoffe, dass ich spätestens dann in der Lage bin sowas zu schreiben ;)


Ich lese mich mal durch!


Schöne Grüße

stargazer
Bitte warten ..
Mitglied: Jenna86
17.07.2011 um 23:34 Uhr
Zitat von stargazer:
Hi Jenna!

Wow. Erstmal vielen Dank für diesen Code, werds gleich mal ausprobieren und versuchen zu verstehen :D

> - Zu allererst erstellst du dir ( am Besten automatisiert ) ein Array mit neuen PictureBoxen.
> Da dich das aber eventuell überfordert hab ich mir tatsächlich mal die Arbeit gemacht das alles zu tippen ^^

Leider wahr. Fange demnächst mit meiner MATSE-Ausbildung an und hoffe, dass ich spätestens dann in der Lage bin sowas zu
schreiben ;)


Ich lese mich mal durch!


Schöne Grüße

stargazer

Na dann viel Spaß beim Durchlesen <:
Falls Rückfragen bleiben sollten, dann frag einfach.

Eine kurze Rückmeldung über einen Erfolg würde mich auch freuen ( damit man sieht, dass sich die "Arbeit" auch gelohnt hat ) ;)

Auf jeden Fall gern geschehen. Mich würde dennoch interessieren, ob die Lösung mit zweidimensionalen Arrays wirklich leichter und unkomplizierter sein sollte als nen verschieben der Boxen. Die komplette Logik, die man dafür braucht ist imho die gleiche Logik wie bei meinem Vorschlag des Zeichnens im Panel.
Also ein "kleiner" Denkanstoß von "dog" wäre nett, damit ich auch die Trivialität des Vorschlags mit den mehrdimensionalen Arrays verstehe (da ich sie aktuell nicht sehe, da in meinen Augen auch einfache Arrays, wie jetzt hier im zweiten Vorschlag genutzt wesentlich simpler erscheinen )
Bitte warten ..
Mitglied: stargazer
18.07.2011 um 01:15 Uhr
Nochmals Hallo,

ich hab mir den Code mal durchgelesen und versucht in meiner Anwendung nachzubauen, aber leider ohne Erfolg. Ich muss allerdings gestehen, dass ich den Code auch nicht wirklich verstehe (hab ja quasi noch nie mit sowas gearbetet ._.), vielleicht liegt das aber auch einfach daran, dass es langsam spät wird und ich sowieso nicht mehr so ganz durchblicke.

Desweiteren gibt es ein Problem mit dem erstellen Randomer Zahlen, denn wenn ich mehrere Zahlen zugleich generieren lasse (die den selben bereich z.B. 1-10 haben) kommt bei allen die selbe Zahl raus.
Ich hab auch schon überlegt anstelle von zufälligen Kombinationen selbige über if-Ketten festzulegen, aber dafür müsste ich mind. 1440 if-Sätze erstellen und für jeden eine Kombination ausdenken, was die Sache auch nicht wirklich einfacher macht.

Ich werde mich morgen nochmal dransetzen, vielleicht bekomme ich dann ja was Gescheites hin.

Außerdem hab ich hier ( http://www.mediafire.com/?ggwj6cpqga53sg2 ) mal das komplette Projekt hochgeladen, falls Interesse besteht.

Schönen Abend noch / Gute Nacht!


stargazer
Bitte warten ..
Mitglied: Jenna86
18.07.2011 um 15:14 Uhr
Das mit den anfangs immer gleichen Zufallszahlen liegt daran, dass es keine "echten" Zufallszahlen sind, sondern eine Zufallszahlensequenz ist, welche mit einem Startwert initialisiert wird. Dazu gibt es aber einiges auf Google glaube ich.
Stichwort "bessere Zufallszahlen C#" oder so. Ich habe leider gerade keine Zeit um mal drüberzugucken, hab doch grad gut was zu tun.
Wenn Beispielsweise der Zufallszahlengenerator mit einer Zeit initialisiert wird und du ohne, dass sich die Zeit ändert mehrfach eine Zufallszahl möchtest, so wird diese immer gleich sein ( wenn ich mich recht erinnere ).

Dass das "Nachbauen" nicht immer hinhaut kann dran liegen, dass deine Variablen anders deklariert sind oder du nur Variablennamen übernimmst, die du vorher nirgends benannt hast.

Wenn du also z.B.:

variable1 = "bla"; schreibst, aber nirgends

String variable1; deklariert hast, dann wirst du einen Fehler bekommen, dass die Variable unbekannt ist oder ähnliches.


Falls ich heute Abend noch Lust haben sollte versuche ich mir deine bisherige Leistung nochmal anzuschauen, ich kann aber nichts versprechen, da ich wie gesagt grad ziemlich was zu tun habe.

Grüße
"Jenna"
Bitte warten ..
Mitglied: stargazer
18.07.2011 um 15:34 Uhr
Hi Jenna,

nochmal vielen Dank, dass du dich da so reinhängst! Hoffe nur, dass all deine Mühe am Ende nicht vergebens ist.
Ich hab in der Zwischenzeit mal angefangen die Uhrzeit auseinander zu pflücken - natürlich wieder mittels Bedingungssätzen. Immerhin habe ich jetzt folgende Werte aufgestellt:

hour1: Gibt den Wert der ersten Ziffer der Stunde aus
hour2: Gibt jeweils den Wert der zweiten Ziffer der Stunde aus
min1: das selbe wie hour1 nur für minuten aus
min2: hour2 für minuten

Ob das so Sinnvoller ist als vorher weiß ich allerdings nicht, aber jetzt muss ich das schonmal nicht jedes mal Manuell machen.

Das mit den Zufallszahlen werd ich mir nochmal anguggn, danke für den Hinweis! Soweit ich mich erinnern kann gab es bei anderen Programmen (z.B. Borland C++ Builder) bezüglich der Randomisierung irgendwie weniger Probleme, oder ich habs einfach nur anders in Erinnerung - wie auch immer.

Ich wünsche noch einen angenehmen Montag!

stargazer
Bitte warten ..
Mitglied: Jenna86
18.07.2011 um 18:44 Uhr
Ich glaube das Wichtigste überhaupt beim Programmieren ist, dass man vorher schon einen "Plan" hat, wie man was lösen möchte.

Ich würde die ganze Uhr mal in verschiedene Teilprobleme unterteilen:

- Anzahl an Punkten pro Box ermitteln
- Anordnung der Punkte per Zufall setzen
- Event, welches jeweils nach einer Sekunde ausgelöst wird und alles zeichnet.

Wenn du das geschafft hast kannst du dir Gedanken drüber machen, wie konkret du das Lösen möchtest

- Anzahl an Punkten pro Box ermitteln:
Für jede Ziffer der Uhrzeit den Wert bestimmen und mit diesem Wert dann die Anzahl der zu zeichnenden Quadrate in jeder Box festlegen
Hierzu einfach etwas Mathe:
Ist eine Zahl größer als 10 und man möchte wissen wie oft sie vorkommt teilt man durch 10. Getreu dem Motto "radieren wir einfach eine Stelle aus". Da C# beim Teilen von int-Variablen keinen Rest berücksichtigt ist das für uns schonmal gut.
Dadurch wird aus 11 / 10 = 1 oder aus 23 / 10 = 2
Die zweite Ziffer die wir wollen ist der Rest, der und bei dieser Teilung abhanden kommt. Diesen Rest bestimmen wir durch eine Modulu Operation.
Hier wird aus 11 % 10 = 1 Rest >1<
Oder aus 23 % 10 = 2 Rest >3<
Bei der Modulu Operation wird also nur der Rest als Ergebnis eingetragen.

- Anordnung der Punkte per Zufall setzen:
Ein Array, dessen Länge die Anzahl der zu zeichnenden Punkte bestimmt
und die Werte des Arrays, die die Position bestimmen
Heißt, ich habe z.B. ein Array der Länge 5, welches 5 Zufallszahlen enthalten soll für die Position.
Jetzt kann ich über eine Schleife die Positionen 1-5 bzw. die Indizes 0-4 durchlaufen und habe so für jeden Punkt der gespeichert ist den Zugriff auf die Position

for (int i = 0 ; i < array.Length ; i++ )
{
PositionDesPunktes = array[i];
}


- Event
TimerObjekt, ich denke, dass das keiner weiteren Klärung bedarf.

Grüße aus dem ( fast leeren ) Büro ^^
Bitte warten ..
Mitglied: Jenna86
18.07.2011 um 20:49 Uhr
Also, wenn ich deinen Code so sehe solltest du zu aller erst wirklich versuchen dich mit grundlegenen Sachen wie der Schleifenprogrammierung auseinanderzusetzen etc.

Du solltest verstehen, dass man anstatt jedes Objekt einzeln zu bennen auch in ein Array ablegen kann und es dort über den Index ansteuern kann, statt über den Namen.

Zu deinem Code:
xaml, hmm. Okay, kenne ich in der Form auch noch nicht, aber grundlegend gibts ja die gleichen Methoden, man muss sie nur finden.

Folgendes:
-Arrays anlegen ( ist wirklich nahezu 1:1 wie ich es gemacht habe, halt.. nein, es ist 1:1 so ). Wo war die Schwierigkeit?

Instanzvariable:
01.
System.Windows.Controls.Image[] block1,block2,block3,block4;
Arrays initialisieren:
01.
        private void initArrays() 
02.
03.
            block1 = new System.Windows.Controls.Image[3]; 
04.
            block1[0] = Image1x1; 
05.
            block1[1] = Image1x2; 
06.
            block1[2] = Image1x3; 
07.
 
08.
            block2 = new System.Windows.Controls.Image[9]; 
09.
            //uswusf 
10.
        }
Array benutzen:
01.
//Einfacher Test für 11:11 
02.
            int num0 = RandomNumber(1, 4); 
03.
            int num1 = RandomNumber(1, 10); 
04.
            int num2 = RandomNumber(1, 6); 
05.
            int num3 = RandomNumber(1, 10); 
06.
 
07.
            // dieser Aufruf ruft das Bild mit Index num0 auf und setzt die Sichtbarkeit 
08.
            // Ist num0 = 1 wird das Bild mit Index 1 gesetzt etc ( Allerdings musst du dann deine Zufallszahlen 
09.
            // bei 0 beginnen lassen. 
10.
            block1[num0].Visibility = Visibility.Visible; 
11.
 
12.
            // dieser Aufruf ersetzt alles folgende: 
13.
            if (num0 == 1) 
14.
                Image1x1.Visibility = Visibility.Visible; 
15.
            if (num0 == 2) 
16.
                Image1x2.Visibility = Visibility.Visible; 
17.
            if (num0 == 3) 
18.
                Image1x3.Visibility = Visibility.Visible; 
19.
 
20.
            //entsprechend fortfahren, dann kannst du die methoden von mir nutzen und nach und nach einbauen 
21.
            //die randomizePosition oder wie sie hieß ist dann dafür da, wenn du mehrere Positionen per Zufall               bestimmen willst
Also, schau dir das nochmal an.
Ich glaube wirklich, dass man noch mehr Hilfe garnicht geben kann.

Wie g ewohnt, bei Rückfragen einfach Fragen
Bitte warten ..
Mitglied: stargazer
19.07.2011 um 18:51 Uhr
Hi Jenna,

ich bin leider immer noch nicht in der Lage den Code zu verstehen. Allerdings liegt das nicht am Code selber, sondern an der Rückmeldung, die das Programm mir gibt, denn wenn ich wie hier...

private void initArrays()
{
block1 = new System.Windows.Controls.Image[3];
block1[0] = Image1x1;
block1[1] = Image1x2;
block1[2] = Image1x3;
block2 = new System.Windows.Controls.Image[9];
uswusf
}


...versuche ein Array zu initialisieren bekomme ich "Der Name 'block1' ist im aktuellen Kontext nicht vorhanden." (Selbiges Problem hatte ich auch im vorigen "PictureBox"-Array-Beispiel, daher konnte ich auch dort nicht nachvollziehen, was du eigentlich gemacht hast...) Muss ich die Namen vielleicht noch vorher irgendwie definieren? Wie gesagt, ich hab kein Plan von Arrays :/


Also hab ich mal ein wenig experimentiert und bin auf das hier gekommen:


private void initArrays()
{
System.Windows.Controls.Image[] block1 = new System.Windows.Controls.Image[3] { Image1x1, Image1x2, Image1x3 };
System.Windows.Controls.Image[] block2 = new System.Windows.Controls.Image[9] { Image2x1, Image2x2, Image2x3, Image2x4, Image2x5, Image2x6, Image2x7, Image2x8, Image2x9 };
System.Windows.Controls.Image[] block3 = new System.Windows.Controls.Image[6] { Image3x1, Image3x2, Image3x3, Image3x4, Image3x5, Image3x6 };
System.Windows.Controls.Image[] block4 = new System.Windows.Controls.Image[9] { Image4x1, Image4x2, Image4x3, Image4x4, Image4x5, Image4x6, Image4x7, Image4x8, Image4x9 };
}

Danach hab ich das Random-System etwas verändert, um einigermaßen randome Zahlen zu erschaffen. Über 4 Timer wird nun in unterschiedlichen Abständen jeweils eine Zahl generiert.

Jetzt wollte ich also mal schnell diesen code ( block1[num0].Visibility = Visibility.Visible; ) in den Timer einbauen, aber leider bekam ich auch hier nun die selbe Fehlermeldung wie vorhin: "Der Name 'block1' ist im aktuellen Kontext nicht vorhanden."

Wie gehe ich diesbezüglich vor?


EDIT


hab den ganzen code
System.Windows.Controls.Image[] block1 = new System.Windows.Controls.Image[3] { Image1x1, Image1x2, Image1x3 };
System.Windows.Controls.Image[] block2 = new System.Windows.Controls.Image[9] { Image2x1, Image2x2, Image2x3, Image2x4, Image2x5, Image2x6, Image2x7, Image2x8, Image2x9 };
System.Windows.Controls.Image[] block3 = new System.Windows.Controls.Image[6] { Image3x1, Image3x2, Image3x3, Image3x4, Image3x5, Image3x6 };
System.Windows.Controls.Image[] block4 = new System.Windows.Controls.Image[9] { Image4x1, Image4x2, Image4x3, Image4x4, Image4x5, Image4x6, Image4x7, Image4x8, Image4x9 };
nun einfach in die Timerfunktion gepackt, jetzt gehts Problemlos.

Wie gehe ich nun am besten vor, wenn ich mehrere pro Block zugleich Sichtbar machen will? Bedingungssätze oder lieder neues Array?


grüße

stargazer


EDIT 2

Hab die Instanzvariable übersehen haha, nochmal von vorn!


EDIT 3

Hab nun alles so gemacht, wie es Sinn ergibt, es tritt jedoch ein runtime error auf ( Eine nicht behandelte Ausnahme des Typs "System.NullReferenceException" ist in Tix Clock.exe aufgetreten ), weshalb ich doch die ganze Arrayerstellung in den Timer versetzt habe. Nun fehlt mir nur noch eine Idee, um die Anzahl der sichtbaren Images für die Stunden festzulegen.
Bitte warten ..
Mitglied: Jenna86
19.07.2011 um 19:57 Uhr
Zitat von stargazer:
Hab nun alles so gemacht, wie es Sinn ergibt, es tritt jedoch ein runtime error auf ( Eine nicht behandelte Ausnahme des Typs
"System.NullReferenceException" ist in Tix Clock.exe aufgetreten ), weshalb ich doch die ganze Arrayerstellung in den
Timer versetzt habe. Nun fehlt mir nur noch eine Idee, um die Anzahl der sichtbaren Images für die Stunden festzulegen.

Hi,

das mit den Instanzvariablen hatte ich schonmal in einer Antwort erwähnt, dass du das beachten musst. Stichwort "Sichtbarkeit von Variablen"
Definierst du eine Variable in einer Methode, so handelt es sich um eine lokale Variable, die nach Beendigung der Methode entfernt wird und somit nur in der Methode, wo sie definiert wird benutzt werden kann.
Instanzvariablen, also Variablen, die du direkt in der Klasse definierst sind in jeder Methode sichtbar und jede Methode kann den Wert lesen / ändern.

System.NullReferenceException tritt auf, wenn du auf einen Index aus einem Array zugreifst, dem einfach noch nichts zugewiesen ist.
Eine IndexOutOfBoundsException tritt auf, wenn du auf einen Index außerhalb der Arraygrenzen zugreifen willst.
Solltest du allerdings alles durch googlen innerhalb von weniger als 30Sekunden finden.

Die Anzahl der Sichtbaren Images für die Stunden... Habe ich grundlegen auch schon alles erklärt und sogar Methoden geliefert, die genau das tun.
01.
>         enum Pos 
02.
>         { 
03.
>             HourFirst, 
04.
>             HourLast, 
05.
>             MinuteFirst, 
06.
>             MinuteLast 
07.
>         } 
08.
> 
Hiermit bekomme ich die Anzahl an Punkten, die im jeweiligen Feld dargestellt werden soll.
01.
>         private int getPointsToDraw(int charOfTime) 
02.
>         { 
03.
>             int pointsToDraw = 0; 
04.
>  
05.
>             switch (charOfTime) 
06.
>             { 
07.
>                 case (int)Pos.HourFirst: 
08.
>                         pointsToDraw = DateTime.Now.Hour / 10; 
09.
>                     break; 
10.
>                 case (int)Pos.HourLast: 
11.
>                         pointsToDraw = DateTime.Now.Hour % 10; 
12.
>                     break; 
13.
>                 case (int)Pos.MinuteFirst: 
14.
>                     pointsToDraw = DateTime.Now.Minute / 10; 
15.
>                     break; 
16.
>                 case (int)Pos.MinuteLast: 
17.
>                     pointsToDraw = DateTime.Now.Minute % 10; 
18.
>                     break; 
19.
>             } 
20.
>             return pointsToDraw; 
21.
>         } 
22.
> 

Zitat von Jenna86:
- Anordnung der Punkte per Zufall setzen:
Ein Array, dessen Länge die Anzahl der zu zeichnenden Punkte bestimmt
und die Werte des Arrays, die die Position bestimmen
Heißt, ich habe z.B. ein Array der Länge 5, welches 5 Zufallszahlen enthalten soll für die Position.
Jetzt kann ich über eine Schleife die Positionen 1-5 bzw. die Indizes 0-4 durchlaufen und habe so für jeden Punkt der
gespeichert ist den Zugriff auf die Position

Zitat von Jenna86:
Die Methode liefert mir eine ArrayListe, welche die Position für das jeweilige Rechteck liefert
01.
>         private ArrayList randomizePositions(int numberofpositions, int numberofshownrecs) 
02.
>         { 
03.
>             Random rand = new Random(DateTime.Now.Millisecond); 
04.
>             ArrayList positions = new ArrayList(); 
05.
>             int tmp = 0; 
06.
>  
07.
>             //get random position(s) for this field 
08.
>             for (int i = 0; i < numberofshownrecs; i++) 
09.
>             { 
10.
>                 while (true) 
11.
>                 { 
12.
>                     tmp = rand.Next(0, numberofpositions); 
13.
>                     if (!positions.Contains(tmp)) 
14.
>                     { 
15.
>                         positions.Add(tmp); 
16.
>                         break; 
17.
>                     } 
18.
>                 } 
19.
>             } 
20.
>  
21.
>             return positions; 
22.
>         } 
23.
> 

Wie du die Methode aufrufst und benutzt findest du im Code weiter oben.
Sie bekommt zwei Parameter übergeben. Der erste Parameter gibt an, wieviele Felder eine zufällige Position bekommen sollen und der zweite Parameter gibt an, wieviele Felder zur Auswahl stehen.
Hast du also z.B. eine "2" für die Minuten, wo es "9" mögliche Felder gibt wird dir diese Methode ein Array der Größe "2" zurückgeben mit zwei zufälligen Positionen.
Also der Index 0, für die erste der zwei Zahlen hat z.B. eine "7", also soll der Punkt in Feld 7 gesetzt werden, wobei der zweite Index im Array, also "1" z.B. eine "2" enthält, wodurch dann der zweite Punkt an die Position "2" gezeichnet wird.

Punktnummer = Index --------- Indexinhalt = Position
array[0] -> Position 7 meinethalben
array[1] -> Position 2
array[2] -> Position 5

so als Beispiel...

Das heißt ich habe drei Punkte die ich zeichnen soll ( weil das Array die Größe 3 hat ) und jeden dieser Punkte setze ich auf die Position, auf die das Array am entsprechenden Index "zeigt".

Noch ein Beispiel:

13:59Uhr

Die Methode getPointsToDraw(int charOfTime) wird für jeden Punkt benutzt um zu wissen, wie viele Punkte man für die Zahl zeichnen muss...
Ob ich nun als Parameter das Enum oder eine Zahl benutze ist geschmackssache.

int anzahlPunkteStelle0 = getPointsToDraw(0); liefert eine 1
int anzahlPunkteStelle1 = getPointsToDraw(1);
liefert eine 3

Alternativ kannst du auch das Enum benutzen ( zur besseren Lesbarkeit )
int anzahlPunkteStelle0 = getPointsToDraw((int)Pos.HourFirst);
int anzahlPunkteStelle1 = getPointsToDraw((int)Pos.HourLast);

Der erste Name im Enum entspricht der 0, der zweite Name der 1 uswusf...

Grüße
Jenna
Bitte warten ..
Mitglied: stargazer
20.07.2011 um 03:09 Uhr
Hi Jenna,

ich möchte mich nochmal ganz Herzlich für deine Mühen bedanken! Ohne dich hätte ich das mit den Arrays bestimmt nicht so schnell geblickt! In diesem Sinne: Danke!

Ich hab das Programm jetzt fertig, teste es noch auf Fehler, die evtl häufiger vorkommen als sie sollten, da ich für das letzte Problem eine andere Lösung "erdacht" habe, als du vorgeschlagen hast - wenn sie auch komplizierter ist (ich habe mit mehreren Timern und Listen gearbeitet, falls du Lust hast dir das anzuguggn lad ich das gern noch hoch <: ).

Demnach ist mein Projekt - dank deiner Hilfe - letzten Endes doch ganz glimpflich verlaufen!

Vielen Dank! Ich hoffe, ich vergesse das nicht alles wieder!


stargazer
Bitte warten ..
Mitglied: Jenna86
20.07.2011 um 18:11 Uhr
Heyho,

es war ja eine schwere Geburt, aber letzten Endes funktioniert es ja schonmal.
Jetzt kannst du ja versuchen noch mehr auf Verständnis zu setzen und dann geht dir das alles auch leichter von der Hand.

Gerne kannst du das Projekt nochmal hochladen, schaut ja optisch schonmal ganz nett aus ( auf Optik habe ich im Vergleich wohl ziemlich 'geschissen' ).
Die Lösung interessiert mich natürlich. Es besteht ja immer die Möglichkeit, dass man noch was lernen kann ( und wenn es durch das "Verbessern" von Code kommt ).

Schön, dass ich dir helfen konnte.

Dann wünsche ich dir viel Spaß mit C#, die Möglichkeiten sind ja quasi unendlich

Grüße
( ein vor lauter Code bald nichts mehr sehen könnender und deshalb gleich Feierabend-machender
)
"Jenna"
Bitte warten ..
Mitglied: stargazer
20.07.2011 um 18:20 Uhr
Peace!

Ich hab das gesamte Projekt nochmal auf Mediafire hochgeladen ( http://www.mediafire.com/?yiggk58xaxxayy7 ). Hab noch n paar kleinigkeiten verändert, allerdings eher Optisch :D

Ich wünsch noch nen schönen Abend!

stargazer
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(8)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Batch & Shell
gelöst Powershell Versteckte Dateien finden und wieder sichtbar machen (4)

Frage von pixel0815 zum Thema Batch & Shell ...

Netzwerkmanagement
WDMYCLOUD nicht im Netzwerk sichtbar (4)

Frage von Ully45 zum Thema Netzwerkmanagement ...

Heiß diskutierte Inhalte
Microsoft
Ordner mit LW-Buchstaben versehen und benennen (20)

Frage von Xaero1982 zum Thema Microsoft ...

Outlook & Mail
gelöst Outlook 2010 findet ost datei nicht (19)

Frage von Floh21 zum Thema Outlook & Mail ...

Netzwerkmanagement
gelöst Anregungen, kleiner Betrieb, IT-Umgebung (18)

Frage von Unwichtig zum Thema Netzwerkmanagement ...