Entwickler-Ecke

WPF / Silverlight - WPF Taschenrechner -- Crash nach Backspace


Kirk1701A - Di 10.10.17 07:31
Titel: WPF Taschenrechner -- Crash nach Backspace
Hey Leute,

Ich bin Azubi im ersten Jahr zum Fachinformatiker. Ich bin grade dabei, ein Taschenrechner zu bauen. Allerdings Crashed der, wenn ich mit Backspace ein Zeichen lösche und ein anderes wieder einsetzen möchte (hauptsächlich bei Operatoren).
Hier mein XAML-Code:

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
<Window x:Class="WpfApplication2.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:Taschenrechner_3"
        mc:Ignorable="d"
        Title="Rechner" Height="350" Width="300" KeyDown="Window_KeyDown" MinWidth="300" MinHeight="350" MaxWidth="600" MaxHeight="650">
    <Grid>
        <Grid.RowDefinitions>
            <!--Zeilen-->
            <RowDefinition Height="16*"/>
            <RowDefinition Height="32*"/>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="40*"/>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="40*"/>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="40*"/>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="40*"/>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="40*"/>
            <RowDefinition Height="10*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="28*"/>
            <ColumnDefinition Width="40*"/>
            <ColumnDefinition Width="10*"/>
            <ColumnDefinition Width="40*"/>
            <ColumnDefinition Width="10*"/>
            <ColumnDefinition Width="40*"/>
            <ColumnDefinition Width="10*"/>
            <ColumnDefinition Width="40*"/>
            <ColumnDefinition Width="30*"/>
        </Grid.ColumnDefinitions>
        <Button x:Name="eins" Content="1" FontSize="16" FontWeight="Bold" Grid.Column="1" Grid.Row="3" Click="eins_click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="zwei" Content="2" FontSize="16" FontWeight="Bold" Grid.Column="3" Grid.Row="3" Click="zwei_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="drei" Content="3" FontSize="16" FontWeight="Bold" Grid.Column="5" Grid.Row="3" Click="drei_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="plus" Content="+" FontSize="16" FontWeight="Bold" Grid.Column="7" Grid.Row="3" Click="plus_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="vier" Content="4" FontSize="16" FontWeight="Bold" Grid.Column="1" Grid.Row="5" Click="vier_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="fünf" Content="5" FontSize="16" FontWeight="Bold" Grid.Column="3" Grid.Row="5" Click="fünf_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="sechs" Content="6" FontSize="16" FontWeight="Bold" Grid.Column="5" Grid.Row="5" Click="sechs_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="minus" Content="-" FontSize="16" FontWeight="Bold" Grid.Column="7" Grid.Row="5" Click="minus_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="sieben" Content="7" FontSize="16" FontWeight="Bold" Grid.Column="1" Grid.Row="7" Click="sieben_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="acht" Content="8" FontSize="16" FontWeight="Bold" Grid.Column="3" Grid.Row="7" Click="acht_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="neun" Content="9" FontSize="16" FontWeight="Bold" Grid.Column="5" Grid.Row="7" Click="neun_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="mal" Content="*" FontSize="16" FontWeight="Bold" Grid.Column="7" Grid.Row="7" Click="mal_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="clean" Content="C" FontSize="16" FontWeight="Bold" Grid.Column="1" Grid.Row="9" Click="clean_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="null" Content="0" FontSize="16" FontWeight="Bold" Grid.Column="3" Grid.Row="9" Click="null_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="komma" Content="." FontSize="16" FontWeight="Bold" Grid.Column="5" Grid.Row="9" Click="komma_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="teil" Content="/" FontSize="16" FontWeight="Bold" Grid.Column="7" Grid.Row="9" Click="teil_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="gleich" Content="=" FontSize="16" FontWeight="Bold" Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="11" Cursor="Hand" Click="gleich_Click" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <Button x:Name="lösch" Content="f" FontSize="16" FontWeight="Bold" FontFamily="Wingdings 3" Grid.Column="5" Grid.ColumnSpan="3" Grid.Row="11" Click="lösch_Click" Cursor="Hand" BorderBrush="Black" IsTabStop="False" Focusable="False"/>
        <TextBox x:Name="rechner" BorderBrush="Black" Background="Cyan" FontSize="17" HorizontalContentAlignment="Right" Grid.Column="3" Grid.ColumnSpan="5" Grid.Row="1" TextAlignment="Right" MaxLines="1" FontFamily="Verdana" FontWeight="Bold" IsTabStop="False" Focusable="False"/>
        <TextBox x:Name="op" BorderBrush="Black" Background="Cyan" FontSize="17" HorizontalContentAlignment="Right" Grid.Column="3" Grid.ColumnSpan="5" Grid.Row="1" TextAlignment="Right" MaxLines="1" FontFamily="Verdana" FontWeight="Bold" IsTabStop="False" Focusable="False" Visibility="Hidden"/>
        <TextBox Name="p" Grid.Column="1" Grid.Row="1" Background="#FFF3F3F3" FontSize="10" TextWrapping="Wrap" TextOptions.TextHintingMode="Fixed" TextOptions.TextFormattingMode="Display" IsEnabled="False" />
    </Grid>
</Window>



Und hier mein C#:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
using System.Windows;
using System.Windows.Input;

namespace WpfApplication2
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        //Variablen zum Rechnen
        double erg1;
        double erg2;

        public MainWindow()
        {
            InitializeComponent();
        }

        //Die nächsten 18 Methoden sind die Buttons, die 1, 2, 3, ... + - * / ... ist-gleich, Backspace, ... schreiben
        private void eins_click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "1";
            p.Text += "1";
        }

        private void zwei_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "2";
            p.Text += "2";
        }

        private void drei_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "3";
            p.Text += "3";
        }

        private void plus_Click(object sender, RoutedEventArgs e)
        {
            op.Text = "+";
            p.Text += "+";
            erg1 += double.Parse(rechner.Text);
            rechner.Clear();
        }

        private void vier_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "4";
            p.Text += "4";
        }

        private void fünf_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "5";
            p.Text += "5";
        }

        private void sechs_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "6";
            p.Text += "6";
        }

        private void minus_Click(object sender, RoutedEventArgs e)
        {
            if (op.Text == "")
            {
                p.Text += "-";
                rechner.Text += "-";
                op.Text = "-";
            }
            else
            {
                p.Text += "-";
                op.Text = "-";
                erg1 += double.Parse(rechner.Text);
                rechner.Clear();
            }
        }

        private void sieben_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "7";
            p.Text += "7";
        }

        private void acht_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "8";
            p.Text += "8";
        }

        private void neun_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "9";
            p.Text += "9";
        }

        private void mal_Click(object sender, RoutedEventArgs e)
        {
            op.Text = "*";
            p.Text += "*";
            erg1 += double.Parse(rechner.Text);
            rechner.Clear();
        }

        private void clean_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text = "";
            p.Text = "";
        }

        private void null_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += "0";
            p.Text += "0";
        }

        private void komma_Click(object sender, RoutedEventArgs e)
        {
            rechner.Text += ",";
            p.Text += ",";
        }

        private void teil_Click(object sender, RoutedEventArgs e)
        {
            op.Text = "/";
            p.Text += "/";
            erg1 += double.Parse(rechner.Text);
            rechner.Clear();
        }

        private void lösch_Click(object sender, RoutedEventArgs e)
        {
            if (rechner.Text == "")
            {
                p.Text = p.Text.Remove(p.Text.Length - 11);
            }
            else
            {
                rechner.Text = rechner.Text.Remove(rechner.Text.Length - 11);
                p.Text = p.Text.Remove(p.Text.Length - 11);
            }
        }

        private void gleich_Click(object sender, RoutedEventArgs e)
        {
            //Rechnungsfunktion
            if (op.Text == "+")
            {
                erg2 = erg1 + double.Parse(rechner.Text);
                rechner.Text = erg2.ToString();
                erg1 = 0;
            }
            else if (op.Text == "-")
            {
                erg2 = erg1 - double.Parse(rechner.Text);
                rechner.Text = erg2.ToString();
                erg1 = 0;
            }
            else if (op.Text == "*")
            {
                erg2 = erg1 * double.Parse(rechner.Text);
                rechner.Text = erg2.ToString();
                erg1 = 0;
            }
            else if (op.Text == "/")
            {
                erg2 = erg1 / double.Parse(rechner.Text);
                rechner.Text = erg2.ToString();
                erg1 = 0;
            }
        }

        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            //Tastenschreiben...
            if (e.Key == Key.NumPad1)
            {
                rechner.Text += "1";
                p.Text += "1";
            }

            else if (e.Key == Key.NumPad2)
            {
                rechner.Text += "2";
                p.Text += "2";
            }

            else if (e.Key == Key.NumPad3)
            {
                rechner.Text += "3";
                p.Text += "3";
            }

            else if (e.Key == Key.NumPad4)
            {
                rechner.Text += "4";
                p.Text += "4";
            }

            else if (e.Key == Key.NumPad5)
            {
                rechner.Text += "5";
                p.Text += "5";
            }

            else if (e.Key == Key.NumPad6)
            {
                rechner.Text += "6";
                p.Text += "6";
            }

            else if (e.Key == Key.NumPad7)
            {
                rechner.Text += "7";
                p.Text += "7";
            }

            else if (e.Key == Key.NumPad8)
            {
                rechner.Text += "8";
                p.Text += "8";
            }

            else if (e.Key == Key.NumPad9)
            {
                rechner.Text += "9";
                p.Text += "9";
            }

            else if (e.Key == Key.NumPad0)
            {
                rechner.Text += "0";
                p.Text += "0";
            }

            else if (e.Key == Key.Add)
            {
                p.Text += "+";
                op.Text = "+";
                erg1 += double.Parse(rechner.Text);
                rechner.Clear();
            }

            else if (e.Key == Key.Subtract)
            {
                if (op.Text == "")
                {
                    p.Text += "-";
                    rechner.Text += "-";
                    op.Text = "-";
                }
                else
                {
                    p.Text += "-";
                    op.Text = "-";
                    erg1 += double.Parse(rechner.Text);
                    rechner.Clear();
                }
            }

            else if (e.Key == Key.Multiply)
            {
                p.Text += "*";
                op.Text = "*";
                erg1 += double.Parse(rechner.Text);
                rechner.Clear();
            }

            else if (e.Key == Key.Divide)
            {
                p.Text += "/";
                op.Text = "/";
                erg1 += double.Parse(rechner.Text);
                rechner.Clear();
            }

            else if (e.Key == Key.Decimal)
            {
                rechner.Text += ",";
                p.Text += ",";
            }

            else if (e.Key == Key.Back)
            {
                if (rechner.Text == "")
            {
                op.Text = op.Text.Remove(op.Text.Length - 11);
            }
            else
            {
                rechner.Text = rechner.Text.Remove(rechner.Text.Length - 11);
                    op.Text = op.Text.Remove(op.Text.Length - 11);
                }
            }

            else if (e.Key == Key.Delete)
            {
                rechner.Text = "";
                p.Text = "";
            }

            else if (e.Key == Key.Return)
            {
                if (op.Text == "+")
                {
                    erg2 = erg1 + double.Parse(rechner.Text);
                    rechner.Text = erg2.ToString();
                    erg1 = 0;
                }
                else if (op.Text == "-")
                {
                    erg2 = erg1 - double.Parse(rechner.Text);
                    rechner.Text = erg2.ToString();
                    erg1 = 0;
                }
                else if (op.Text == "*")
                {
                    erg2 = erg1 * double.Parse(rechner.Text);
                    rechner.Text = erg2.ToString();
                    erg1 = 0;
                }
                else if (op.Text == "/")
                {
                    erg2 = erg1 * double.Parse(rechner.Text);
                    rechner.Text = erg2.ToString();
                    erg1 = 0;
                }
            }
        }

    }
}


Danke für eure Hilfe.

Euer Kirk


Delete - Di 10.10.17 08:10

- Nachträglich durch die Entwickler-Ecke gelöscht -


Kirk1701A - Di 10.10.17 08:18

Hi,

Der Cursor ist im unteren Beispiel [CURSOR].

[CURSOR]erg1 += double.Parse(rechner.Text);

Egal ob "+ - * /" der bleibt immer an der Stelle beim Debuggen (und Backspace) stecken und crashed.

Euer Kirk

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Delete - Di 10.10.17 08:23

- Nachträglich durch die Entwickler-Ecke gelöscht -


Kirk1701A - Di 10.10.17 08:29

Das is bei jedem Fragment so.

Also:

Wenn ich "3+3+" eingegeben habe, möchte ich das letzte + löschen (mit Backspace) und ein z.B. - einsetzen, also "3+3-...". Wenn ich das + gelöscht habe "3+3" und nun ein (in diesem Beispiel) - einsetzen möchte, crashed das Programm. Das is bei jeder Rechenart so und unabhängig davon, ob ich es mit Button oder Tastatur mache. Der stürzt immer ab. Am besten ist es, wenn du "3+3+" eingibst, mit Backspace-Button oder -Taste, das letzte + löschst, und stattdessen ein + oder - oder * oder / eingibst (auch egal ob mit Button oder Taste).

Hoffe, du verstehst das.


jaenicke - Di 10.10.17 08:42

Es gibt auch Double.TryParse [https://msdn.microsoft.com/de-de/library/system.double.tryparse(v=vs.110).aspx], womit du nicht einfach in eine Zahl umwandelst, sondern nachschauen kannst, ob das überhaupt geht.

Denn wenn der Wert z.B. leer ist, schlägt die Umwandlung in einen Zahlenwert fehl.


Th69 - Di 10.10.17 08:45

Hallo und :welcome:

wenn du beim Debuggen einen Fehler erhältst, dann deutet dies auf eine Exception hin (s.a. Ausnahmen und Ausnahmebehandlung [https://docs.microsoft.com/de-de/dotnet/csharp/programming-guide/exceptions/]).
In deinem Fall ist dies die double.Parse-Methode, welche eine Exception auslöst, weil wohl keine (einzelne) Zahl in der übergebenen Variablen rechner steht.
Sobald der Debugger eine (unbehandelte) Exception anzeigt, kannst du dir im "Überwachen"-Fenster (engl. "Watch window") die Variableninhalte anzeigen lassen (s. Fenster "Überwachen" und "Schnellüberwachung" [https://msdn.microsoft.com/de-de/library/0taedcee.aspx]).

Verwende besser die double.TryParse [https://msdn.microsoft.com/de-de/library/system.double.tryparse(v=vs.110).aspx]-Methode, um evtl. Fehler abzufangen.


Kirk1701A - Di 10.10.17 08:51

Danke.

Ich probiers gleich mal aus und gebe euch dann eine Rückmeldung. :zustimm: :idea:


Kirk1701A - Di 10.10.17 09:40

Langsam, aber sicher bin ich mit der Sache überfordert.

Ich habe das erstmal am "plus_Click" probiert, komme aber irgendwie nicht weiter. :lupe:
Hier der "plus_Click"-Code, nach aktuellem Stand.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
private void plus_Click(object sender, RoutedEventArgs e)
        {
            double t;
            op.Text = "+";
            p.Text += "+";
            erg1 = double.TryParse("+"out t);
            rechner.Clear();
        }

VS sagt mir: "Der Typ 'bool' kann nicht implizit in 'double' konvertiert werden."
Ich habe es, bevor ich das TryParse genommen habe, damit versucht, dass, wenn Backspace gemacht wird, dass op(also da, wo die Operatoren sitzen) gereinigt wird. Das hat der auch gemacht, aber als ich dann einen Operatoren einsetzen wollte, hat es trotzdem nicht funktioniert. :autsch:

Was allerdings komisch ist, ist, dass es vor 2 Tagen funktioniert hat. Und da sah der Code wie gaanz oben aus (Eröffnungsbeitrag). :autsch:


Th69 - Di 10.10.17 10:13

Die Methode funktioniert etwas anders als die Parse: sie gibt einen bool-Wert zurück, der angibt, ob die Umwandlung erfolgreich war:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if (double.TryParse(rechner.Text, out erg1))
{
  // Umwandlung erfolgreich und in 'erg1' steht der Zahlenwert
}
else
{
  // Umwandlung nicht erfolgreich -> z.B. Fehler ausgeben
}

Der untere Fall sollte natürlich bei deinem Programm niemals auftreten, aber so kannst du nach und nach die logischen Fehler bei deinem Programmcode korrigieren. ;-)


Kirk1701A - Di 10.10.17 10:27

Wow, Danke.
Allerdings wirft der mir was ganz anderes raus, was ich will. z.B. "3/2" ist eigentlich 1,5; aber der zeigt mir "2" an.

Ich weiss nicht, ob Ihr das wisst (bitte nicht persönlich nehmen, ok? :eyes: ), aber "rechner" ist das Textfeld bzw. die TextBox, in der hineingeschrieben wird und das Ergebnis am Ende steht.
Ich zeig mal schnell, was ich für Mist fabriziert habe.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
 private void teil_Click(object sender, RoutedEventArgs e)
        {
            op.Text = "/";
            p.Text += "/";

            if (double.TryParse(rechner.Text, out erg1))
            {
                erg1 += double.Parse(rechner.Text);
                rechner.Clear();
            }
            else
            {
                rechner.Text = "ERROR!";
            }
        }


Ich weiss echt nicht mehr weiter. :autsch: :cry: :bawling: :nixweiss: :nixweiss:

Moderiert von user profile iconChristian S.: Beiträge zusammengefasst

oder habe ich das falsch verstanden?

Moderiert von user profile iconChristian S.: Beiträge zusammengefasst

Was ich vergessen habe, ist, dass wenn ich den oben beschriebenen Fehler mal ausführe (also bei "3+3+" das letzte + wegmachen und hier ein / einsetze), kommt "ERROR!".

D.h. der kann das nicht machen, oder?


Ralf Jansen - Di 10.10.17 10:38

Zitat:
Allerdings wirft der mir was ganz anderes raus, was ich will. z.B. "3/2" ist eigentlich 1,5; aber der zeigt mir "2" an.


Parse/TryParse rechnen nicht. Es wandelt nur einen string in einen anderen Typ zum Beispiel double um. Wenn du irgendwo 3/2 gerechnet hast und dabei 2 raus kommt dann hast du eine Ganzzahl Division durchgeführt und keine Floatingpoint Division. Das Problem liegt dann aber vorher und nicht beim Parse bzw. TryParse.


Kirk1701A - Di 10.10.17 10:45

Kurioser Weise hat mein Taschenrechner erst so gut gerechnet, seit ich die parse-Methode habe. Ich habe auch noch eine andere Version eines Taschenrechners, an der ich gearbeitet habe, die allerdings keine längeren Terme (Rechnungen) zulässt. Also: "3+3" geht, aber "3+3+3" geht schon nicht mehr.

Alte Version eines Taschenrechners:



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
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 Taschenrechner
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        //Schreiben mit den Buttons ("eins_Click" schreibt 1, ...)
        private void eins_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "1";
        }

        private double erg1;
        private double erg2;
        private void zwei_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "2";
        }

        private void plus_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "+";
        }

        private void drei_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "3";
        }

        private void vier_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "4";
        }

        private void fünf_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "5";
        }

        private void sechs_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "6";
        }

        private void minus_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "-";
        }

        private void sieben_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "7";
        }

        private void acht_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "8";
        }

        private void neun_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "9";
        }

        private void mult_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "*";
        }

        private void komma_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += ",";
        }

        private void null_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "0";
        }

        private void clean_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text = "";
        }

        private void teil_Click(object sender, RoutedEventArgs e)
        {
            this.Rechnerbox.Text += "/";
        }
        //Einzelne Zeichen löschen -> wie Backspace
        private void lösch_Click(object sender, RoutedEventArgs e)
        {
            if (Rechnerbox.Text.Length > 0)
            {
                Rechnerbox.Text = Rechnerbox.Text.Substring(0, Rechnerbox.Text.Length - 1);
            }
        }
        //Klammern...
        private void kla_Click(object sender, RoutedEventArgs e)
        {
            //...auf
            this.Rechnerbox.Text += "(";
        }

        private void klz_Click(object sender, RoutedEventArgs e)
        {
            //...zu
            this.Rechnerbox.Text += ")";
        }

        //Die Ist-Gleich-Funktion -> wenn's nicht funktioniert, kommt "Error!"
        private void gleich_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                result(); //Verweist zum private void unten...
            }
            //Jetzt kommt Error
            catch (Exception exc)
            {
                Rechnerbox.Text = "Error!";
            }
        }
        //...Eingabe von + - * /
        private void result()
        {
            //Prüfung, wo sich die Operatoren befinden
            String op;
            int iOp = 0;
            if (Rechnerbox.Text.Contains("+"))
            {
                iOp = Rechnerbox.Text.IndexOf("+");
            }
            else if (Rechnerbox.Text.Contains("-"))
            {
                iOp = Rechnerbox.Text.IndexOf("-");
            }
            else if (Rechnerbox.Text.Contains("*"))
            {
                iOp = Rechnerbox.Text.IndexOf("*");
            }
            else if (Rechnerbox.Text.Contains("/"))
            {
                iOp = Rechnerbox.Text.IndexOf("/");
            }
            else
            {
                //Error
            }
            

            //Rechnung nachdem = gedrückt wurde
            op = Rechnerbox.Text.Substring(iOp, 1);
            double op1 = Convert.ToDouble(Rechnerbox.Text.Substring(0, iOp));
            double op2 = Convert.ToDouble(Rechnerbox.Text.Substring(iOp + 1, Rechnerbox.Text.Length - iOp - 1));
            
            
            //Operatorenprüfung
            if (op == "+"//Operator "Plus"
            {
                Rechnerbox.Text = "" + (op1 + op2);
            }
            else if (op == "-"//Operator "Minus"
            {
                Rechnerbox.Text = "" + (op1 - op2);
            }
            else if (op == "*"//Operator "Mal"
            {
                Rechnerbox.Text = "" + (op1 * op2);
            }
            else //Operator "Geteilt"
            {
                Rechnerbox.Text = "" + (op1 / op2);
            }
           
        }
    }
}





XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
<Window x:Class="Taschenrechner.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:Taschenrechner"
        mc:Ignorable="d"
        Title="Taschenrechner" Height="420.784" Width="372.209" Background="#FF00D1FF" ResizeMode="CanMinimize" BorderBrush="Black" Foreground="Black">
    <Grid Margin="0,0,0,-21">
        <Grid.Background>
            <SolidColorBrush Color="#FF00E8FF"/>
        </Grid.Background>
        <TextBlock x:Name="Text" Height="35" Margin="9,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold" FontStyle="Italic" FontSize="22" Width="319"><Run Text="Taschenrechner (Ver. 1."/><Run Text="1"/><Run Text=")"/><Run Text=" Beta"/></TextBlock>
        <TextBox Name="Rechnerbox" Height="35" Margin="10,63,10,0" VerticalAlignment="Top" TextAlignment="Right" FontSize="19" BorderBrush="Black" MaxLines="1" Cursor="IBeam" FontWeight="Bold" SelectionBrush="{x:Null}" Background="White" Foreground="Black"/>
        <Grid Margin="22,121,29,31" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Button x:Name="eins" Content="1" Height="40" Width="40" Margin="8,20,234,155" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="eins_Click" Cursor="Hand"/>
            <Button x:Name="zwei" Content="2" Height="40" Width="40" Margin="50,13,186,149" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="zwei_Click" Cursor="Hand"/>
            <Button x:Name="drei" Content="3" Height="40" Width="40" Margin="95,13,141,149" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="drei_Click" Cursor="Hand"/>
            <Button x:Name="plus" Content="+" Height="40" Width="40" Margin="135,0,90,136" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="plus_Click" Cursor="Hand"/>
            <Button x:Name="vier" Content="4" Height="40" Width="40" Margin="5,59,231,103" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="vier_Click"/>
            <Button x:Name="fünf" Content="5" Height="40" Width="40" Margin="50,59,186,103" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="fünf_Click"/>
            <Button x:Name="sechs" Content="6" Height="40" Width="40" Margin="98,66,144,109" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="sechs_Click"/>
            <Button x:Name="minus" Content="-" Height="40" Width="40" Margin="135,46,90,90" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="minus_Click" Cursor="Hand"/>
            <Button x:Name="sieben" Content="7" Height="40" Width="40" Margin="8,110,234,65" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="sieben_Click" Cursor="Hand"/>
            <Button x:Name="acht" Content="8" Height="40" Width="40" Margin="53,110,189,65" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="acht_Click" Cursor="Hand"/>
            <Button x:Name="neun" Content="9" Height="40" Width="40" Margin="98,110,144,65" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="neun_Click" Cursor="Hand"/>
            <Button x:Name="mult" Content="*" Height="40" Width="40" Margin="151,126,106,81" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="mult_Click" Cursor="Hand"/>
            <Button x:Name="null" Content="0" Height="40" Width="40" Margin="50,149,186,13" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="null_Click" Cursor="Hand"/>
            <Button x:Name="clean" Content="C" Height="40" Width="40" Margin="8,156,234,19" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="clean_Click" Cursor="Hand"/>
            <Button x:Name="teil" Content="/" Height="40" Width="40" Margin="151,172,106,35" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="teil_Click" Cursor="Hand"/>
            <Button x:Name="lösch" Content="f" FontFamily="Wingdings 3"  Height="40" Margin="191,20,7,155" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Width="84" Click="lösch_Click" Cursor="Hand"/>
            <Button x:Name="gleich" Content="=" Height="84" Margin="191,66,51,65" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Width="40" Click="gleich_Click" Cursor="Hand"/>
            <Button x:Name="Komma" Content="." Height="40" Width="40" Margin="106,172,151,35" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="komma_Click" Cursor="Hand"/>
            <Button x:Name="kla" Content="(" Height="40" Width="40" Margin="242,126,15,81" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="kla_Click" Cursor="Hand" Command="Close"/>
            <Button x:Name="klz" Content=")" Height="40" Width="40" Margin="242,82,15,125" FontSize="18" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Click="klz_Click" Cursor="Hand" Command="Close"/>
        </Grid>
        <TextBlock x:Name="Text2" Height="35" Margin="10,351,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Width="319" Text="Dies ist eine ungetestete Beta-Version"/>
    </Grid>
</Window>


Kirk1701A - Di 10.10.17 10:46

Hier lag es am "IndexOf".


Kirk1701A - Di 10.10.17 10:50

Sry, bin vom Thema abgewichen.
Ähmm, ich weiss aber nicht, wie ich dann eine Rechenfunktion stellen soll. :nixweiss:

Aber, wie gesagt, der Taschenrechner gaaanz oben hat erst so gut gerechnet, seit dieses "double.Parse(...)" drin ist.


Th69 - Di 10.10.17 12:23

Gibst du "3+3+" etc. direkt in die TextBox ein oder aber über die Buttons?
In der TextBox darf nur eine einzelne Zahl stehen (aber sonst keine anderen Zeichen), wenn du Parse/TryParse aufrufst - sonst erhältst du eben eine Exception bzw. false als Ergebnis)!!!

Halte dich an die Funktionalität eines realen Taschenrechners, d.h. immer bei jeder Operation die vorherige Operation ausführen, d.h.

Quelltext
1:
2:
3:
4:
3
+
3
/

Jetzt 3+3 rechnen und das Ergebnis intern in einer Variablen merken und in die TextBox zurückschreiben - und als Operation '/' merken.
Und nach

Quelltext
1:
2:
2
=

dann wieder die letzte Operation ('/') ausführen und das Ergebnis in die TextBox zurückschreiben.
Mit Backspace solltest du nur die letzte Ziffer einer Zahl löschen (aber nicht die Operation). Setze daher am besten (ersteinmal) "readonly" bei der TextBox, so daß der Anwender komplett die Buttons benutzen muß.

Einen Parser mit beliebigen Ausdrücken zu schreiben, ist etwas komplizierter (u.a. wegen unterschiedlicher Operatorprioriäten und Klammern) - dafür habe ich Parser für mathematische Formeln [http://www.mycsharp.de/wbb2/thread.php?threadid=71995] entwickelt. ;-)

PS: Der nächste Schritt wäre es, wenn du dein Programm auf MVVM (Model View ViewModel) [https://de.wikipedia.org/wiki/Model_View_ViewModel] umschreibst, denn dies ist die übliche Vorgehensweise bei WPF. So kannst du dann die Anwendungslogik komplett unabhängig von der UI entwickeln und testen!


Kirk1701A - Di 10.10.17 13:15

Die TextBox ist so eingestellt, dass man nicht hineinklicken kann (hast du das nicht ausprobiert? :?: ).

Es gibt aber 2 Möglichkeiten, die Zahlen einzugeben:
1. per Buttons
2. per Tastatur (genauer: NumPad)

Rechnen tut der schon ganz gut. Längere Rechnungen, Minuszahlen, Dezimalzahlen, verschiedene Rechenarten in einer Rechnung, ...
Mir ist nur wichtig, dass ich, wenn ich einen Operatoren lösche, dass ich (ohne Crash) einen neuen einsetzen kann.


Hinweis: Es hat schon einmal so funktioniert!


Ralf Jansen - Di 10.10.17 13:50

Zitat:
Die TextBox ist so eingestellt, dass man nicht hineinklicken kann (hast du das nicht ausprobiert? :?: ).


Üblich ist sein Problem soweit herunter zu brechen das ausprobieren für uns eher unnötig sein sollte. Es ist also nicht hilfreich wenn man seinen ganzen Code hier einfach reinwirft oder schlimmer noch den ganzen Code verschiedener Versionen seines Entwicklungsstands und dann noch von diversen Änderungen spricht die man daran vorgenommen hat weiß irgendwann keiner mehr was genau jetzt dein Problem womit ist. Du solltest es Helfern einfach machen und nicht verwirren. Dann verlieren Helfer potentiell nur ihre LUst am helfen. Heißt selber Problemstellen ausmachen und diese zeigen ohne den ganzen nicht problemrelevanten Boilerplate Code. Wenn mehr nötig wird werden Helfer dich schon darauf hinweisen und nach mehr fragen. Wenn dann etwas zum ausprobieren nötig ist dann auch eher als angehängtes Projekt (z.B. als Zip ohne Executeable oder Objektdateien) so das man das einfach bei sich ausprobieren kann und nicht erst aufwendig ein Projekt basteln muß.

Zitat:
Mir ist nur wichtig, dass ich, wenn ich einen Operatoren lösche, dass ich (ohne Crash) einen neuen einsetzen kann.


Dann mal kurz Hilfe zur Selbsthilfe ;)
a.) Etwas crasht nicht einfach so. Das System spricht mit dir und sagt dir welche Exception geworfen wurde etc. Diese Details sind wichtig. Auch wenn dir das noch nichts sagt uns könnten sie was sagen. Also was für eine Exception bekommst du?
b.) Was steht in den beteiligten Variablen? Wenn es irgendwo knallt solltest du einfach mal in die beteiligten Variablen schauen und deine Annahmen gegen das checken was da wirklich drin steckt. Z.B. was steht den zum Zeitpunkt an dem es knallt in der Variablen die du in Parse/TryParse reingibst drin?


Kirk1701A - Di 10.10.17 14:11

Okay, ich seh ein, dass ich mein Problem nicht korrekt geschildert habe. Also mache ich das jetzt richtig:

Ich baue gerade an einem ganz einfachen Taschenrechner, der die Grundrechenarten, negative -, und Dezimalzahlen beherrschen soll. Die Eingabe geschieht über Buttons oder NumPad. Als Beispiel zur Schilderung nehme ich die Rechnung "3+3/3".

Ich gebe "3+3+" ein. Ich habe mich vertippt und möchte nun das letzte + korrigieren. Also drücke ich die Backspace-Taste oder -Button (extra angelegt). Nun steht "3+3" in einer separaten TexBox. Wenn ich nun "/" eingebe für "3+3/...", stürzt mein Programm ab und setzt die Ausnahme auf meine double.Parse (Code kommt gleich). Das ist mit [b]allen[/b] Rechenarten so. Egal ob "3-3*..." oder etc.

Hier nun mein Code:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
 private void teil_Click(object sender, RoutedEventArgs e)
        {
            op.Text = "/";
            p.Text += "/";
            erg1 += double.Parse(rechner.Text);
            rechner.Clear();
        }


Wenn ich debugg mache, geht der bis zu "erg1" und zeigt die Exception. Ich habe mich über die "double.Parse" Methode echt gefreut, weil erst dadurch mein Taschenrechner rechnen konnte.

Der "rechner" oben im Code ist eine TextBox, in die nicht hineingeklickt werden kann.

Ich hoffe, ihr ... verzeiht mir wegen meiner bescheidenen Erläuterung vorhin.


Lebt lang und in Freiden

Euer Kirk


Ralf Jansen - Di 10.10.17 14:15

Zitat:
Wenn ich debugg mache, geht der bis zu "erg1" und zeigt die Exception. Ich habe mich über die "double.Parse" Methode echt gefreut, weil erst dadurch mein Taschenrechner rechnen konnte.

Der "rechner" oben im Code ist eine TextBox, in die nicht hineingeklickt werden kann.


Zu dem Zeitpunkt wo die Exception angezeigt wird schau was in rechner.Text drinsteht. Und bedenke double.Parse rechnet nicht es wandelt einen string in eine Zahl und 3+3 ist keine Zahl. Das Ergebnis wäre eine Zahl der Ausdruck selbst aber nicht.


Kirk1701A - Di 10.10.17 14:24

Stell dir vor, du hast 1 TextBox und 1 Label. In die TextBox wird die Rechnung eingegeben (per Button oder NumPad). Du willst "3+3+3" rechnen. Also gibst du auch "3+3+3" ein. Der Clou ist, ich habe es so programmiert, dass wenn du "+" oder "-" oder "*" oder "/" drückst, die TextBox geleert wird, aber im Label komplett angezeigt wird. Außerdem habe ich eine versteckte TextBox, in der das (hier) "+" gespeichert wird. Die Variable "erg1" rechnet den Label-Inhalt indirekt schon aus und speichert es in "erg1". Wenn du "3+3" schon stehen hast, hat der das Ergebnis in "erg1" vom Label (also 6) schon hinterlegt, dass wenn du jetzt "+3" weiter eingibst, der im Prinzip "6+3" rechnet, was (weiss ja jeder) 9 ist.

Wenn du was nicht verstanden hast, schreib einfach, bin bis etwa 15:55 Uhr noch online (theoretisch). :zwinker:


Lebt lang und in Friden

Euer Kirk


Kirk1701A - Di 10.10.17 14:52

Was ich vergessen habe hinzuschreiben, ist, dass es bei Zahlen funktioniert. D.h. wenn ich statt (bei der Rechnung "3+3+3") aus Versehen "3+3+5" eingegeben habe, kann ich ganz leicht, ohne Abstürze, die "5" in eine "3" ändern.


Th69 - Di 10.10.17 16:42

Wir können (und werden) nicht die Fehler in deinem Code suchen und diesen verbessern - das mußt du schon selber tun. Lerne mit dem Debugger umzugehen: Erste Schritte mit dem Debugger [https://msdn.microsoft.com/de-de/library/mt243867.aspx].

Wie ich schon schrieb, macht es keinen Sinn, den Operator per Backspace-Taste zu löschen, sondern üblicherweise drückt man dann einfach den anderen Operator (und überschreibt damit den letzten Operator).


Kirk1701A - Fr 03.11.17 14:30

Jolan Tru Leute,

danke an alle, die mir geholfen haben. Ich habe jetzt einen Taschenrechner fertiggestellt mit dem Extra, dass da ein Sternzeitrechner drin ist. Wer interesse an einen Sternzeitrechner hat, meldet sich bei mir bitte per pn und bekommt ihn innerhalb von 14 Tagen. Es ist auch möglich ihn mit dem Taschenrechner zu bekommen. Natürlich alles kostenfrei und unverbindlich und ohne Datenabfrage. Ich schreibe mir lediglich nur eure Profilnamen auf, um zu wissen, wer schon eins bekommen hat.

Euer Kirk