WPF & C#: Erweiterte Stoppuhr erstellen - Fehlermeldungen?

2 Antworten

Etwas, was für Fehlermeldungen sorgen könnte (die du im Fragetitel erwähnst), sehe ich in deinem Code so direkt nicht. Im Beschreibungstext gehst du auch nicht weiter darauf ein. Das heißt, wenn du welche bekommst, wirst du erst einmal weiterhin auf dich allein gestellt sein. In der Hinsicht kann ich nur dazu raten, die jeweiligen Meldungen genau zu lesen, denn sie geben in der Regel Auskunft über Art und Fundstelle.

Das die Ausgabe mit der, die auf dem Screenshot vorgegeben ist, nicht übereinstimmt, sollte klar sein. Du legst ja explitizt ein anderes Format fest:

L_Ausgabe.Content = "0 : 0 : 0 : 0";

Um die Zahlen mit führender 0 zu berechnen, gibt es verschiedene Ansätze. Du kannst zum einen (ganzzahlig) durch 10 dividieren (bei dreistelligen Zahlen zusätzlich durch 100) oder aber du vergleichst, ob die aktuelle Zahl über 9 liegt (bei dreistelligen Zahlen zusätzlich, ob über 99) oder nicht.

Bezüglich der Anordnung der Elemente musst du im XAML View vielleicht noch etwas tun (für mich nicht beurteilbar, denn du dazu ja keine Angaben gemacht). Ein Grid mit zwei Spalten dürfte für die Grundanordnung reichen. In diesen könnte man weitere Unterteilungen, z.B. mit einem StackPanel (oder erneut präziser mit einem Grid) vornehmen.

Beispiel:

<Grid Margin="10">
  <Grid.ColumnDefinitions>
    <ColumnDefinition />
    <ColumnDefinition />
  </Grid.ColumnDefinitions>

  <StackPanel Margin="0, 0, 5, 0" Orientation="Vertical">
    <!-- label and buttons ... -->
  </StackPanel>
  <ListBox Grid.Column="1" Margin="5, 0, 0, 0" />
</Grid>

Die Anzahl an ColumnDefinition-Tags bestimmt die Spaltenanzahl (equivalent dazu gibt es RowDefinitions für Reihen). Je Definition kannst du eine Höhe / Breite vorgeben. Entweder mit absoluten Werten oder protentual.

Beispiel für eine 70%-30%-Aufteilung:

<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.3*" />

Prinzipiell kannst du Grids und StackPanels ineinander verschachteln. Ebenso könntest du ein einziges großes Grid verwenden. Mit den Attributen Grid.Column und Grid.Row kannst du auf den Kindelementen bestimmen, in welche Spalte / Reihe sie sollen (die Zählung startet bei 0, Standardwert ist 0). Um den Platz mehrerer Zeilen / Reihen zu beanspruchen, gibt es Grid.ColumnSpan und Grid.RowSpan.

Probiere dich da selbst einmal etwas aus. Das Autosuggestion-Feature von Visual Studio wird dir helfen. Andernfalls bleibt dir immer noch die Option, die Oberflächengestaltung mit Hilfe von Drag & Drop sowie dem Properties-Dialog (wird bei Selektion einer Oberflächenkomponente angezeigt) zu erledigen.

Was ich im Übrigen noch ändern würde: Der Button zum Starten des Timers sollte, wenn der Timer läuft, mit Stopp (oder Pause) betitelt werden. Wenn er nicht läuft, mit Start. So wird dem Nutzer eindeutig vermittelt, welche Aktion der Button beim nächsten Klick ausführen wird.

PS.: Die Tatsache, dass du es als notwendig empfindest, die Bedeutung deiner Variablen noch einmal separat zu erklären, sollte eigentlich ein Fahnenschwenk sein, der darauf hinweist, dass die derzeitigen Bezeichner schlecht gewählt sind. Vergib eindeutige, aussagekräftige Namen (und das möglichst ohne Sprachmix). Dein Button zum Zurücksetzen der Zeit könnte bspw. ResetButton heißen.

Moin,

das wäre mein Vorschlag:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

namespace WpfApp1

{

  /// <summary>

  /// Interaction logic for MainWindow.xaml

  /// </summary>

  public partial class MainWindow : Window

  {

    public MainWindow()

    {

      InitializeComponent();

      aTimer = new System.Timers.Timer();

      aTimer.Interval = 1;

      aTimer.Elapsed += OnTimedEvent;

      aTimer.AutoReset = true;

       

    }

    private System.Timers.Timer aTimer;

    private int zs = 0, sek = 0, min = 0, h = 0;

    private bool pruef = true;

    private void B_zwz_Click(object sender, RoutedEventArgs e)

    {

      ListBox1.Items.Add(L_Ausgabe.Content);

    }

    private void B_zurueck_Click(object sender, RoutedEventArgs e)

    {

      aTimer.Stop();

      B_Start.Content = "Start";

      L_Ausgabe.Content = " 0: 0 :0 : 0 ";

      ListBox1.Items.Clear();

    }

    private void button_Click(object sender, RoutedEventArgs e)

    {

      if (pruef)

      {

        aTimer.Enabled = true;

        aTimer.Start();

        B_Start.Content = "Stop";

        pruef = false;

      }

      else

      {

        aTimer.Stop();

        B_Start.Content = "Start";

        pruef = true;

      }

    }

    private void changeLabel() {

      L_Ausgabe.Content = h + " : " + min + " : " + sek + " : " + zs;

    }

    private void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)

    {

      try

      {

        zs++;

        if (zs == 10)

        {

          sek++;

          zs = 0;

        }

        else if (sek == 60)

        {

          sek = 0;

          min++;

        }

        else if (min == 60)

        {

          min = 0;

          h++;

        }

        else if (h == 24)

        {

          h = 0;

        }

        this.L_Ausgabe.Dispatcher.Invoke(changeLabel);

      }

      catch

      {

        return;

      }

    }

  }

}

--------------------------------------------------------------------------------------------------------

<Window x:Class="WpfApp1.MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    xmlns:local="clr-namespace:WpfApp1"

    mc:Ignorable="d"

    Title="MainWindow" Height="450" Width="800">

  <Grid>

    <Label x:Name="L_Ausgabe" Content="&quot;0 : 0 : 0 : 0&quot;" HorizontalAlignment="Left" Margin="147,145,0,0" VerticalAlignment="Top" RenderTransformOrigin="-4.065,0.891" Width="89"/>

    <Button x:Name="B_Start" Content="Start" HorizontalAlignment="Left" Margin="93,0,0,0" VerticalAlignment="Center" Height="35" Width="180" Click="button_Click"/>

    <Button x:Name="B_zwz" Content="Mark" HorizontalAlignment="Left" Margin="93,267,0,0" VerticalAlignment="Top" Height="35" Width="73" Click="B_zwz_Click"/>

    <Button x:Name="B_zurueck" Content="Reset" HorizontalAlignment="Left" Margin="200,267,0,0" VerticalAlignment="Top" Height="35" Width="73" Click="B_zurueck_Click"/>

    <ListBox x:Name="ListBox1" Margin="400,108,146,108"/>

  </Grid>

</Window>

Nahimic  17.08.2021, 08:56

Oh sorry ignoriere die Antwort. Hab gerade erst gesehen, dass es um die Darstellung geht. Als ich das ausgeführt hatte lief die Zeit nicht kontinuierlich und das hatte ich stattdessen gelöst.

0