erste commit
This commit is contained in:
commit
bcf89dd9fb
289
.gitignore
vendored
Normal file
289
.gitignore
vendored
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
|
||||||
|
# Visual Studio 2015 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUNIT
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
**/Properties/launchSettings.json
|
||||||
|
|
||||||
|
# VS Code
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_i.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# JustCode is a .NET coding add-in
|
||||||
|
.JustCode
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/packages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/packages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/packages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Typescript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
.idea/
|
||||||
|
*.sln.iml
|
||||||
|
|
||||||
|
# CodeRush
|
||||||
|
.cr/
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
233
README.md
Normal file
233
README.md
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
# Sportwetten EV Calculator
|
||||||
|
|
||||||
|
Hallo und willkommen!
|
||||||
|
Dies ist ein kleines Projekt, das wir mit C# und WPF gemacht haben.
|
||||||
|
Die App hilft, potenziellen Gewinn und Erwartungswert (EV) für Sportwetten zu berechnen. Man gibt Quoten und eine geschätzte Gewinnwahrscheinlichkeit ein, und das Programm zeigt, ob eine Wette sich lohnt oder nicht.
|
||||||
|
|
||||||
|
Wir haben das Projekt gemacht, um WPF besser zu lernen und Mathe mit Programmierung zu verbinden. Es ist ein einfaches Übungsprojekt für Bildung.
|
||||||
|
|
||||||
|
## Wie benutzt man die App?
|
||||||
|
1. Starte das Programm.
|
||||||
|
2. Gib deinen Betrag ein.
|
||||||
|
3. Gib deine geschätzte Gewinnwahrscheinlichkeit ein (zwischen 0 und 1).
|
||||||
|
4. Wähle die Wettart: „Einzeln" oder „Kombi".
|
||||||
|
5. Gib die Quoten ein.
|
||||||
|
6. Klicke auf Berechnen.
|
||||||
|
7. Es wird angezeigt, Info über die Wett, wie viel Gewinn möglich ist und ob der Erwartungswert positiv oder negativ ist.
|
||||||
|
|
||||||
|
## Eingabetypen
|
||||||
|
|
||||||
|
Numerische Eingaben:
|
||||||
|
|
||||||
|
Betrag (decimal)
|
||||||
|
Gewinnwahrscheinlichkeiten (decimal zwischen 0 und 1)
|
||||||
|
Quoten (decimal)
|
||||||
|
|
||||||
|
|
||||||
|
Auswahleingaben:
|
||||||
|
|
||||||
|
Wettart (Einzeln/Kombi)
|
||||||
|
|
||||||
|
## Was ist drin?
|
||||||
|
- C#
|
||||||
|
- WPF
|
||||||
|
- Mathematische Logik für die EV-Berechnung
|
||||||
|
|
||||||
|
## Dateien
|
||||||
|
- MainWindow.xaml – Layout der App mit deklarativem UI-Aufbau
|
||||||
|
- MainWindow.xaml.cs – Logik, Events und Berechnungen
|
||||||
|
- README.md – Diese Datei hier
|
||||||
|
|
||||||
|
### XAML-Struktur (Auszug)
|
||||||
|
```xml
|
||||||
|
<Window x:Class="WpfApp2.MainWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="EV Wetten Rechner" Height="557" Width="500">
|
||||||
|
<Grid Margin="15">
|
||||||
|
<!-- ... -->
|
||||||
|
<StackPanel Grid.Row="4" Margin="0,0,0,15">
|
||||||
|
<Label Content="Quoten:" FontWeight="SemiBold"/>
|
||||||
|
<StackPanel x:Name="quottenPanel">
|
||||||
|
<!-- Hier werden die Quoten-Elemente dynamisch eingefügt -->
|
||||||
|
</StackPanel>
|
||||||
|
<Button x:Name="kpfAddQuotten" Content="+ Weitere Quote hinzufügen"
|
||||||
|
Click="kpfAddQuottenGedrückt"/>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- ... -->
|
||||||
|
<ScrollViewer Grid.Row="6" VerticalScrollBarVisibility="Auto">
|
||||||
|
<StackPanel x:Name="ergebnisPanel">
|
||||||
|
<!-- Hier werden die Ergebnisse dynamisch eingefügt -->
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verwendete Formeln für Erwartungswert (EV)
|
||||||
|
|
||||||
|
### Für Einzelwetten und Kombiwetten:
|
||||||
|
```
|
||||||
|
EV = (Gewinnwahrscheinlichkeit × Potenzieller Gewinn) - (Verlustwahrscheinlichkeit × Einsatz)
|
||||||
|
```
|
||||||
|
Dabei ist:
|
||||||
|
- Gewinnwahrscheinlichkeit: Die geschätzte Chance auf Gewinn (zwischen 0 und 1)
|
||||||
|
- Verlustwahrscheinlichkeit: 1 - Gewinnwahrscheinlichkeit
|
||||||
|
- Potenzieller Gewinn: Einsatz × (Quote - 1)
|
||||||
|
- Einsatz: Der gesetzte Betrag
|
||||||
|
|
||||||
|
Aus unserem Code:
|
||||||
|
```csharp
|
||||||
|
decimal gewinnWahrscheinlichkeit = probability;
|
||||||
|
decimal verlustWahrscheinlichkeit = 1 - gewinnWahrscheinlichkeit;
|
||||||
|
decimal potenziellerGewinn = betrag * (summe - 1);
|
||||||
|
decimal ev = (potenziellerGewinn * gewinnWahrscheinlichkeit) - (betrag * verlustWahrscheinlichkeit);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Für Kombiwetten zusätzlich:
|
||||||
|
```
|
||||||
|
Gesamtquote (summe) = Quote1 × Quote2 × ... × QuoteN
|
||||||
|
```
|
||||||
|
|
||||||
|
Im Code multiplizieren wir alle Quoten miteinander:
|
||||||
|
```csharp
|
||||||
|
decimal summe = 1.0m;
|
||||||
|
for (int i = 0; i < quoteTextBoxes.Count; i++)
|
||||||
|
{
|
||||||
|
// Für jede eingegebene Quote
|
||||||
|
if (!string.IsNullOrWhiteSpace(oddBox.Text))
|
||||||
|
{
|
||||||
|
decimal quote = Convert.ToDecimal(oddBox.Text);
|
||||||
|
summe = summe * quote;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Technische Herausforderungen und Lösungen
|
||||||
|
|
||||||
|
Während der Entwicklung dieses Projekts stießen wir auf mehrere technische Herausforderungen, die wir durch passende Lösungsansätze überwinden konnten:
|
||||||
|
|
||||||
|
### 1. Dynamische UI-Elemente generieren
|
||||||
|
Ein Hauptproblem war das dynamische Erstellen von StackPanels für die Eingabe mehrerer Quoten bei Kombiwetten. Anstatt diese fest im XAML zu definieren, mussten wir sie zur Laufzeit generieren.
|
||||||
|
|
||||||
|
**Lösung**: Wir haben die Methode `QuotenInputErzeuger` entwickelt, die UI-Elemente programmatisch erstellt:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
private void QuotenInputErzeuger(int index)
|
||||||
|
{
|
||||||
|
//ein Stackpanel zu herstellen
|
||||||
|
StackPanel rowPanel = new StackPanel();
|
||||||
|
rowPanel.Orientation = Orientation.Horizontal;
|
||||||
|
|
||||||
|
//ein Label zu herstellen
|
||||||
|
Label label = new Label();
|
||||||
|
label.Content = "Quoten der " + index + "-x Wette:";
|
||||||
|
label.Width = 150;
|
||||||
|
|
||||||
|
//ein neu TextBox zu erzeugen, um quote zu geben
|
||||||
|
TextBox textBox = new TextBox();
|
||||||
|
textBox.Width = 100;
|
||||||
|
textBox.Height = 25;
|
||||||
|
|
||||||
|
//Label und textbox zu Stackpanel zu addieren
|
||||||
|
rowPanel.Children.Add(label);
|
||||||
|
rowPanel.Children.Add(textBox);
|
||||||
|
|
||||||
|
//die neu Stackpanel zu der MainWindow.xaml Stackpanel zu addieren
|
||||||
|
quottenPanel.Children.Add(rowPanel);
|
||||||
|
quoteTextBoxes.Add(textBox);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Wir verwenden den `System.Windows.Controls`-Namespace, um UI-Elemente wie StackPanel, Label und TextBox programmatisch zu erzeugen und zu manipulieren. Diese Lösung ermöglicht es uns, die Anzahl der Quoten-Eingabefelder dynamisch an die Wettart (Einzeln oder Kombi) anzupassen.
|
||||||
|
|
||||||
|
Für die Verwaltung dieser dynamisch erzeugten Elemente haben wir eine Liste implementiert:
|
||||||
|
```csharp
|
||||||
|
private List<TextBox> quoteTextBoxes;
|
||||||
|
```
|
||||||
|
|
||||||
|
Diese Liste speichert alle erzeugten TextBox-Objekte, sodass wir später auf ihre Werte zugreifen können:
|
||||||
|
```csharp
|
||||||
|
for (int i = 0; i < quoteTextBoxes.Count; i++)
|
||||||
|
{
|
||||||
|
TextBox oddBox = quoteTextBoxes[i];
|
||||||
|
if (!string.IsNullOrWhiteSpace(oddBox.Text))
|
||||||
|
{
|
||||||
|
decimal quote = Convert.ToDecimal(oddBox.Text);
|
||||||
|
// Weiterer Code...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Präzise Berechnungen mit geeignetem Datentyp
|
||||||
|
Anfangs hatten wir Probleme mit der Genauigkeit bei Berechnungen, als wir `double` und `float` verwendeten. Wir erhielten oft ungenaue Ergebnisse oder sogar 0 als Output.
|
||||||
|
|
||||||
|
**Lösung**: Wir haben uns für den `decimal`-Datentyp entschieden, der besonders für Finanzberechnungen geeignet ist:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// Aus unserem Code:
|
||||||
|
decimal probability = Convert.ToDecimal(txtGewinnWahrscheinlichkeit.Text);
|
||||||
|
decimal betrag = Convert.ToDecimal(txtBetrag.Text);
|
||||||
|
decimal summe = 1.0m; // Gesamtquote, "m" kennzeichnet decimal-Literal
|
||||||
|
|
||||||
|
// Berechnung des Erwartungswerts
|
||||||
|
decimal gewinnWahrscheinlichkeit = probability;
|
||||||
|
decimal verlustWahrscheinlichkeit = 1 - gewinnWahrscheinlichkeit;
|
||||||
|
decimal potenziellerGewinn = betrag * (summe - 1);
|
||||||
|
decimal ev = (potenziellerGewinn * gewinnWahrscheinlichkeit) - (betrag * verlustWahrscheinlichkeit);
|
||||||
|
```
|
||||||
|
|
||||||
|
Der `decimal`-Datentyp bietet 28-29 signifikante Stellen und ist damit deutlich präziser als `double` (15-16 Stellen) oder `float` (7 Stellen) für unsere finanzmathematischen Berechnungen. Besonders bei der Berechnung von Prozenten und Quoten hat sich dieser Datentyp als viel genauer erwiesen.
|
||||||
|
|
||||||
|
### 3. Dynamische Ergebnisanzeige
|
||||||
|
Eine weitere Herausforderung war die dynamische Darstellung der Ergebnisse. Wir haben die Methode `ZeigeErgebnis` implementiert, die anhand der Berechnungen passende UI-Elemente erzeugt:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
private void ZeigeErgebnis(decimal ev, decimal betrag, decimal summe, int anzahlWetten, decimal probability)
|
||||||
|
{
|
||||||
|
ergebnisPanel.Children.Clear(); // Bestehende Ergebnisse löschen
|
||||||
|
|
||||||
|
// Stackpanel für info erzeugen
|
||||||
|
StackPanel infoPanel = new StackPanel();
|
||||||
|
|
||||||
|
// Wettart bestimmen (Einzeln oder Kombi)
|
||||||
|
string wettart;
|
||||||
|
if (rkEinzeln.IsChecked == true)
|
||||||
|
{
|
||||||
|
wettart = "Einzeln";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wettart = anzahlWetten + "x Kombi";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Informationen und Bewertung dynamisch anzeigen
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Warum haben wir das gemacht?
|
||||||
|
- Wir wollten lernen, wie man GUI-Anwendungen mit C# und WPF entwickelt.
|
||||||
|
- Das Thema Wetten ist gut zum Üben, weil man mit Quoten, Wahrscheinlichkeiten und einfachem Rechnen arbeiten kann.
|
||||||
|
- Die App ist nicht für echtes Wetten gedacht, sondern als Lernhilfe.
|
||||||
|
|
||||||
|
## Nächste Schritte und geplante Verbesserungen
|
||||||
|
Für zukünftige Versionen der Anwendung planen wir folgende Verbesserungen:
|
||||||
|
1. Zurück-Button implementieren
|
||||||
|
Ein Button zum Zurücksetzen der Eingaben oder zum Zurückkehren zu einem vorherigen Zustand soll hinzugefügt werden:
|
||||||
|
2. Fehlerbehandlung mit Try-Catch verbessern
|
||||||
|
Aktuell verwenden wir einfache Validierungen. Für eine robustere Anwendung sollen Try-Catch-Blöcke implementiert werden:
|
||||||
|
|
||||||
|
## Etwas zum Schluss
|
||||||
|
- Das Projekt ist nicht perfekt, aber es war gut zum Lernen.
|
||||||
|
|
||||||
|
## Arbeitsverteilung:
|
||||||
|
+Iyad Sassoui:Hat leider nichts gemacht
|
||||||
|
+Ismail Amara:Hat die Nachirchten für Exceptions (NullorWhite space/ein Zahl größe als 1 und kleine als 0 ) gemacht ,auch er hat mit Abdelaziz Elouazzani Event Handler Methode gemacht und er hat Ideen und Verbesserungsvorschlag geggeben.
|
||||||
|
+Abdelaziz Elouazzani:Er war verantwortlich für die Rest der Code für MainWindow.xaml.cs und MainWindow.xaml (Layout) und README Datei
|
||||||
|
|
||||||
|
## die Quelle ,die wir genutzt haben,um probleme zu löschen sind:
|
||||||
|
-https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls?view=windowsdesktop-9.0&viewFallbackFrom=net-5.0
|
||||||
|
-https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.stackpanel?view=windowsdesktop-9.0
|
||||||
|
-https://www.youtube.com/watch?v=WYBoTT2ce8c&list=PLKShHgmYjjFwmuUZ46GxeSTA2zKZF-8nv&index=1
|
||||||
|
-https://winnerodds.com/what-is-expected-value-with-calculator/
|
25
WpfApp2/WpfApp2.sln
Normal file
25
WpfApp2/WpfApp2.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.13.35931.197 d17.13
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfApp2", "WpfApp2\WpfApp2.csproj", "{3EF1D1B2-B1ED-4F0D-99F7-C75D0809B813}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{3EF1D1B2-B1ED-4F0D-99F7-C75D0809B813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{3EF1D1B2-B1ED-4F0D-99F7-C75D0809B813}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{3EF1D1B2-B1ED-4F0D-99F7-C75D0809B813}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{3EF1D1B2-B1ED-4F0D-99F7-C75D0809B813}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {420D8004-F2F6-4646-8B49-153C4C120779}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
9
WpfApp2/WpfApp2/App.xaml
Normal file
9
WpfApp2/WpfApp2/App.xaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<Application x:Class="WpfApp2.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:WpfApp2"
|
||||||
|
StartupUri="MainWindow.xaml">
|
||||||
|
<Application.Resources>
|
||||||
|
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
14
WpfApp2/WpfApp2/App.xaml.cs
Normal file
14
WpfApp2/WpfApp2/App.xaml.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Configuration;
|
||||||
|
using System.Data;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace WpfApp2
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for App.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class App : Application
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
10
WpfApp2/WpfApp2/AssemblyInfo.cs
Normal file
10
WpfApp2/WpfApp2/AssemblyInfo.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
[assembly: ThemeInfo(
|
||||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// or application resource dictionaries)
|
||||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// app, or any theme specific resource dictionaries)
|
||||||
|
)]
|
61
WpfApp2/WpfApp2/MainWindow.xaml
Normal file
61
WpfApp2/WpfApp2/MainWindow.xaml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<Window x:Class="WpfApp2.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:WpfApp2"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="EV Wetten Rechner" Height="557" Width="500">
|
||||||
|
<Grid Margin="15">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="0" Text="Erwartungswert Wetten Rechner"
|
||||||
|
FontSize="20" FontWeight="Bold" Margin="0,0,0,20"
|
||||||
|
HorizontalAlignment="Center"/>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Margin="0,0,0,15">
|
||||||
|
<Label Content="Wie viel Geld hast du gewettet?" FontWeight="SemiBold"/>
|
||||||
|
<TextBox x:Name="txtBetrag" Height="30" Width="150" HorizontalAlignment="Left"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Margin="0,0,0,15">
|
||||||
|
<Label Content="Deine geschätzte Gewinnwahrscheinlichkeit (0-1):" FontWeight="SemiBold"/>
|
||||||
|
<TextBox x:Name="txtGewinnWahrscheinlichkeit" Height="30" Width="150" HorizontalAlignment="Left"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="3" Margin="0,0,0,15">
|
||||||
|
<Label Content="Wettart:" FontWeight="SemiBold"/>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<RadioButton x:Name="rkEinzeln" Content="Einzeln" Margin="0,0,15,0" Checked="WettArtRadioAusgewählt"/>
|
||||||
|
<RadioButton x:Name="rkParlay" Content="Parlay (Kombi)" Checked="WettArtRadioAusgewählt"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="4" Margin="0,0,0,15">
|
||||||
|
<Label Content="Quoten:" FontWeight="SemiBold"/>
|
||||||
|
<StackPanel x:Name="quottenPanel">
|
||||||
|
</StackPanel>
|
||||||
|
<Button x:Name="kpfAddQuotten" Content="+ Weitere Quote hinzufügen" Width="200"
|
||||||
|
HorizontalAlignment="Left" Margin="0,10,0,0" Padding="5"
|
||||||
|
Click="kpfAddQuottenGedrückt"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="5" Orientation="Horizontal" Margin="0,10,0,20">
|
||||||
|
<Button x:Name="kpfBerechnen" Content="Berechnen" Width="100" Height="30"
|
||||||
|
Margin="0,0,10,0" Click="kpfBerechnenGedrückt"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<ScrollViewer Grid.Row="6" VerticalScrollBarVisibility="Auto">
|
||||||
|
<StackPanel x:Name="ergebnisPanel">
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
247
WpfApp2/WpfApp2/MainWindow.xaml.cs
Normal file
247
WpfApp2/WpfApp2/MainWindow.xaml.cs
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace WpfApp2
|
||||||
|
{
|
||||||
|
public partial class MainWindow : Window
|
||||||
|
{
|
||||||
|
//Fileds:List für Quotte zu Speichern und ein index Variable,um aktuelle wett zu bestimmen
|
||||||
|
private List<TextBox> quoteTextBoxes;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public MainWindow()
|
||||||
|
{
|
||||||
|
//Constructor Method
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
//Quote List zu intitialisieren
|
||||||
|
quoteTextBoxes = new List<TextBox>();
|
||||||
|
|
||||||
|
// radio button von Einzeln art Wett automatisch ausgewählt
|
||||||
|
rkEinzeln.IsChecked = true;
|
||||||
|
QuottePanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup Method für Quote Panel
|
||||||
|
private void QuottePanel()
|
||||||
|
{
|
||||||
|
index = 1;
|
||||||
|
|
||||||
|
//löschen all angegebene quote
|
||||||
|
quottenPanel.Children.Clear();
|
||||||
|
quoteTextBoxes.Clear();
|
||||||
|
|
||||||
|
if (rkEinzeln.IsChecked == true)
|
||||||
|
{
|
||||||
|
QuotenInputErzeuger(index);
|
||||||
|
|
||||||
|
//versteckt die AddQuote button ,wenn die einzeln button ist ausgewählt
|
||||||
|
kpfAddQuotten.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QuotenInputErzeuger(index);
|
||||||
|
|
||||||
|
//AddQuote button ist jetzt sichtbar ,um neu Quotte hinzufügen
|
||||||
|
kpfAddQuotten.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
//index wird actualiesiert
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Method ,der dynamisch Stackpanel erzeugt
|
||||||
|
private void QuotenInputErzeuger(int index)
|
||||||
|
{
|
||||||
|
|
||||||
|
//ein Stackpanel zu herstellen
|
||||||
|
StackPanel rowPanel = new StackPanel();
|
||||||
|
rowPanel.Orientation = Orientation.Horizontal;
|
||||||
|
|
||||||
|
//ein Label zu herstellen
|
||||||
|
Label label = new Label();
|
||||||
|
label.Content = "Quoten der " + index + "-x Wette:";
|
||||||
|
label.Width = 150;
|
||||||
|
|
||||||
|
//ein neu TextBox zu erzeugen ,um quote zu geben
|
||||||
|
TextBox textBox = new TextBox();
|
||||||
|
textBox.Width = 100;
|
||||||
|
textBox.Height = 25;
|
||||||
|
|
||||||
|
//Label und textbox zu Stackpanel zu addieren
|
||||||
|
rowPanel.Children.Add(label);
|
||||||
|
rowPanel.Children.Add(textBox);
|
||||||
|
|
||||||
|
//die neu Stackpanel zu der MainWindow.xaml Stackpanel zu addieren
|
||||||
|
quottenPanel.Children.Add(rowPanel);
|
||||||
|
quoteTextBoxes.Add(textBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ereignis Hanldler | Das Ereignis: Wett Art radio button auswählen
|
||||||
|
private void WettArtRadioAusgewählt(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
//Setup Quotte Methode zu rufen
|
||||||
|
QuottePanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ereignis Handler | Das Ereignis: Add Quotte KNopf drücken
|
||||||
|
private void kpfAddQuottenGedrückt(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
//Neu Stackpanel zu erzeugen
|
||||||
|
QuotenInputErzeuger(index);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ereignis Handler | Das Ereignis: Berechnen Knopf drücken
|
||||||
|
private void kpfBerechnenGedrückt(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
//zeigt ein Nachricht wenn nichts wird angegeben
|
||||||
|
if (string.IsNullOrWhiteSpace(txtBetrag.Text))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Bitte geben Sie den Wetteinsatz ein.", "Fehler");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//zeigt ein Nachricht wenn nichts wird angegeben
|
||||||
|
if (string.IsNullOrWhiteSpace(txtGewinnWahrscheinlichkeit.Text))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Bitte geben Sie Ihre geschätzte Gewinnwahrscheinlichkeit ein (Wert zwischen 0 und 1).", "Fehler");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Convertiert input von string zu decimal input
|
||||||
|
decimal probability = Convert.ToDecimal(txtGewinnWahrscheinlichkeit.Text);
|
||||||
|
|
||||||
|
//zeigt ein Nachricht wenn die gewinnwharscheinlichkeit ist größe als 1 oder kleiner als 0
|
||||||
|
if (probability < 0 || probability > 1)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Wahrscheinlichkeit muss zwischen 0 und 1 sein!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Convertiert Betrag input von string zu decimal input
|
||||||
|
decimal betrag = Convert.ToDecimal(txtBetrag.Text);
|
||||||
|
|
||||||
|
//Variable für die Summe der Quotten (einzeln=1 || Kombi=quotte1*quotte2*...00*
|
||||||
|
decimal summe = 1.0m;
|
||||||
|
|
||||||
|
//Der Anzahl der Alle Wettw
|
||||||
|
int anzahlWetten = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < quoteTextBoxes.Count; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
//Variable ,der jeder Quotte speichert
|
||||||
|
TextBox oddBox = quoteTextBoxes[i];
|
||||||
|
|
||||||
|
//Bedigung:es muss am meindestens eine Quotte wird angegeben
|
||||||
|
if (!string.IsNullOrWhiteSpace(oddBox.Text))
|
||||||
|
{
|
||||||
|
//Cobvertiert Quotte von string zu decimal
|
||||||
|
decimal quote = Convert.ToDecimal(oddBox.Text);
|
||||||
|
summe = summe * quote;
|
||||||
|
|
||||||
|
//Anzahl der Wetten wird aktualiesiert
|
||||||
|
anzahlWetten++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anzahlWetten == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Bitte geben Sie mindestens eine Quote ein.", "Fehler");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
decimal gewinnWahrscheinlichkeit = probability;
|
||||||
|
decimal verlustWahrscheinlichkeit = 1 - gewinnWahrscheinlichkeit;
|
||||||
|
decimal potenziellerGewinn = betrag * (summe - 1);
|
||||||
|
decimal ev = (potenziellerGewinn * gewinnWahrscheinlichkeit) - (betrag * verlustWahrscheinlichkeit);
|
||||||
|
|
||||||
|
//Gibt ZeigErgebnis Method Argumments
|
||||||
|
ZeigeErgebnis(ev, betrag, summe, anzahlWetten, gewinnWahrscheinlichkeit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Zeigt die Wettart, Betrag, Gesamtquote, Wahrscheinlichkeiten, potenzieller Gewinn und Erwartungswert
|
||||||
|
private void ZeigeErgebnis(decimal ev, decimal betrag, decimal summe, int anzahlWetten, decimal probability)
|
||||||
|
{
|
||||||
|
ergebnisPanel.Children.Clear();
|
||||||
|
|
||||||
|
//Stackpanel für info erzeugen
|
||||||
|
StackPanel infoPanel = new StackPanel();
|
||||||
|
|
||||||
|
string wettart;
|
||||||
|
//Speicher der Art der Wett zu wettart variable
|
||||||
|
if (rkEinzeln.IsChecked == true)
|
||||||
|
{
|
||||||
|
wettart = "Einzeln";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wettart = anzahlWetten + "x Kombi";
|
||||||
|
}
|
||||||
|
|
||||||
|
//TextBlock zeigt die Wettart
|
||||||
|
TextBlock wettartBlock = new TextBlock();
|
||||||
|
wettartBlock.Text = "Wettart: " + wettart;
|
||||||
|
infoPanel.Children.Add(wettartBlock);
|
||||||
|
|
||||||
|
//Convertiert Berechnungen zu Prozent
|
||||||
|
decimal probabilityProzent = probability * 100;
|
||||||
|
decimal quoteWhascheinlichkeit = (1 / summe) * 100;
|
||||||
|
decimal gewinn = betrag * (summe - 1);
|
||||||
|
|
||||||
|
//Ein TextBlock für Info erzeugen
|
||||||
|
TextBlock infoBlock = new TextBlock();
|
||||||
|
|
||||||
|
infoBlock.Text = "*******************INFO*******************\n";
|
||||||
|
infoBlock.Text += "Betrag = " + betrag + "\n";
|
||||||
|
infoBlock.Text += "Summe der Quoten = " + summe + "\n";
|
||||||
|
infoBlock.Text += "Ihre geschätzte Gewinnwahrscheinlichkeit = " + Math.Round(probabilityProzent, 2) + "\n";
|
||||||
|
infoBlock.Text += "Implizite Wahrscheinlichkeit (1/Quote) = " + Math.Round(quoteWhascheinlichkeit, 2) + "\n";
|
||||||
|
infoBlock.Text += "Potenzieller Gewinn = " + Math.Round(gewinn, 2) + "€" + "\n";
|
||||||
|
infoBlock.Text += "*******************INFO*******************";
|
||||||
|
|
||||||
|
//Addiere Textblock der Info zu stack panel
|
||||||
|
infoPanel.Children.Add(infoBlock);
|
||||||
|
|
||||||
|
//Addiere Stackpanel zu stackpanel,der in MainWindow.xaml steht.
|
||||||
|
ergebnisPanel.Children.Add(infoPanel);
|
||||||
|
|
||||||
|
//Stackpanel für ev und bewertung zu erzeugen
|
||||||
|
StackPanel evPanel = new StackPanel();
|
||||||
|
|
||||||
|
//TextBlock für ev erzeugen
|
||||||
|
TextBlock evWertBlock = new TextBlock();
|
||||||
|
evWertBlock.Text = "Der Erwartungswert ist: " + ev ;
|
||||||
|
evWertBlock.FontWeight = FontWeights.Bold;
|
||||||
|
|
||||||
|
//Addiere Textblock der eb zu stackpanel
|
||||||
|
evPanel.Children.Add(evWertBlock);
|
||||||
|
|
||||||
|
//Textblock für Bewertung erzeugen
|
||||||
|
TextBlock evBewertung = new TextBlock();
|
||||||
|
if (ev < 0)
|
||||||
|
{
|
||||||
|
evBewertung.Text = "Negative EV - Diese Wette ist mathematisch nicht profitabel.";
|
||||||
|
}
|
||||||
|
else if (ev > 0)
|
||||||
|
{
|
||||||
|
evBewertung.Text = "Positive EV - Diese Wette hat einen mathematischen Vorteil!";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
evBewertung.Text = "EV ist Null - Diese Wette ist fair.";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Textblock der Bewertung zu Stackpanel addieren
|
||||||
|
evPanel.Children.Add(evBewertung);
|
||||||
|
|
||||||
|
//Stackpanel der ev und bewertung zu Stackpanel ,der in MainWindow.xaml steht.
|
||||||
|
ergebnisPanel.Children.Add(evPanel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
WpfApp2/WpfApp2/WpfApp2.csproj
Normal file
11
WpfApp2/WpfApp2/WpfApp2.csproj
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net9.0-windows</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
Loading…
x
Reference in New Issue
Block a user