diff --git a/samples/Sentry.Samples.Wpf/App.xaml b/samples/Sentry.Samples.Wpf/App.xaml
new file mode 100644
index 0000000000..9577f99adf
--- /dev/null
+++ b/samples/Sentry.Samples.Wpf/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/samples/Sentry.Samples.Wpf/App.xaml.cs b/samples/Sentry.Samples.Wpf/App.xaml.cs
new file mode 100644
index 0000000000..73a0acf78a
--- /dev/null
+++ b/samples/Sentry.Samples.Wpf/App.xaml.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Navigation;
+using Sentry.Protocol;
+
+namespace Sentry.Samples.Wpf
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ public App()
+ {
+ // TODO: Should be part of Sentry.Wpf and hook automatically
+ DispatcherUnhandledException += (sender, e) =>
+ {
+ if (e.Exception is Exception ex)
+ {
+ ex.Data[Mechanism.HandledKey] = e.Handled;
+ ex.Data[Mechanism.MechanismKey] = "App.DispatcherUnhandledException";
+ _ = SentrySdk.CaptureException(ex);
+ }
+
+ if (!e.Handled)
+ {
+ // Unhandled will crash the app so flush the queue:
+ SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)).GetAwaiter().GetResult();
+ }
+ };
+
+ SentrySdk.Init(o =>
+ {
+ o.Dsn = "https://eb18e953812b41c3aeb042e666fd3b5c@o447951.ingest.sentry.io/5428537";
+ // TODO: Should print to VS debug window (similar to Sentry for ASP.NET)
+ o.Debug = true;
+ // TODO: Doesn't support multiple instances of the process on the same directory yet
+ o.CacheDirectoryPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ // For testing, set to 100% transactions for performance monitoring.
+ o.TracesSampleRate = 1.0;
+ });
+ }
+
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ SentrySdk.AddBreadcrumb("OnStartup", "app.lifecycle");
+ SentrySdk.ConfigureScope(s => s.Transaction = SentrySdk.StartTransaction("Startup", "app.start"));
+ base.OnStartup(e);
+ }
+
+ protected override void OnNavigating(NavigatingCancelEventArgs e)
+ {
+ SentrySdk.AddBreadcrumb("NavigatingCancelEventArgs",
+ "navigation",
+ data: new Dictionary
+ {
+ {"url", e.Uri.ToString()}
+ });
+ base.OnNavigating(e);
+ }
+
+ protected override void OnFragmentNavigation(FragmentNavigationEventArgs e)
+ {
+ SentrySdk.AddBreadcrumb("OnFragmentNavigation",
+ "navigation",
+ data: new Dictionary
+ {
+ {"fragment", e.Fragment},
+ {"handled", e.Handled.ToString()}
+ });
+ base.OnFragmentNavigation(e);
+ }
+
+ protected override void OnExit(ExitEventArgs e)
+ {
+ base.OnExit(e);
+ SentrySdk.Close();
+ }
+ }
+}
diff --git a/samples/Sentry.Samples.Wpf/AssemblyInfo.cs b/samples/Sentry.Samples.Wpf/AssemblyInfo.cs
new file mode 100644
index 0000000000..8b5504ecfb
--- /dev/null
+++ b/samples/Sentry.Samples.Wpf/AssemblyInfo.cs
@@ -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)
+)]
diff --git a/samples/Sentry.Samples.Wpf/MainWindow.xaml b/samples/Sentry.Samples.Wpf/MainWindow.xaml
new file mode 100644
index 0000000000..85722fdaa6
--- /dev/null
+++ b/samples/Sentry.Samples.Wpf/MainWindow.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/samples/Sentry.Samples.Wpf/MainWindow.xaml.cs b/samples/Sentry.Samples.Wpf/MainWindow.xaml.cs
new file mode 100644
index 0000000000..b7c2f9902b
--- /dev/null
+++ b/samples/Sentry.Samples.Wpf/MainWindow.xaml.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Windows;
+
+namespace Sentry.Samples.Wpf
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ public MainWindow() => InitializeComponent();
+
+ private ISpan _initSpan;
+
+ public override void BeginInit()
+ {
+ _initSpan = SentrySdk.GetSpan()?.StartChild("BeginInit");
+ base.BeginInit();
+ }
+
+ public override void EndInit()
+ {
+ base.EndInit();
+ _initSpan?.Finish();
+ // Is this the API to close the current transaction bound to the scope? Maybe we need to revisit this..
+ SentrySdk.ConfigureScope(s => s.Transaction?.Finish());
+ }
+
+ private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
+ => throw new InvalidOperationException("This button shall not be pressed!");
+ }
+}
diff --git a/samples/Sentry.Samples.Wpf/Sentry.Samples.Wpf.csproj b/samples/Sentry.Samples.Wpf/Sentry.Samples.Wpf.csproj
new file mode 100644
index 0000000000..a6e5d7da84
--- /dev/null
+++ b/samples/Sentry.Samples.Wpf/Sentry.Samples.Wpf.csproj
@@ -0,0 +1,13 @@
+
+
+
+ WinExe
+ net6.0-windows
+ true
+
+
+
+
+
+
+