Resolving warnings and treating warnings as errors in WinUI project. (#824)

This commit is contained in:
Burak Kaan Köse
2026-02-27 20:12:43 +01:00
committed by GitHub
parent d2fce5eee1
commit 0e742c7a8f
55 changed files with 336 additions and 269 deletions
@@ -16,7 +16,7 @@ public class ApplicationResourceManager : IApplicationResourceManager<ResourceDi
=> WinoApplication.Current.Resources.ContainsKey(resourceKey);
public ResourceDictionary GetLastResource()
=> WinoApplication.Current.Resources.MergedDictionaries.LastOrDefault();
=> WinoApplication.Current.Resources.MergedDictionaries.LastOrDefault()!;
public void ReplaceResource(string resourceKey, object resource)
=> WinoApplication.Current.Resources[resourceKey] = resource;
@@ -9,10 +9,10 @@ namespace Wino.Mail.WinUI.Services;
public class ConfigurationService : IConfigurationService
{
public T Get<T>(string key, T defaultValue = default)
public T Get<T>(string key, T defaultValue = default!)
=> GetInternal(key, ApplicationData.Current.LocalSettings.Values, defaultValue);
public T GetRoaming<T>(string key, T defaultValue = default)
public T GetRoaming<T>(string key, T defaultValue = default!)
=> GetInternal(key, ApplicationData.Current.RoamingSettings.Values, defaultValue);
public void Set(string key, object value)
@@ -21,11 +21,13 @@ public class ConfigurationService : IConfigurationService
public void SetRoaming(string key, object value)
=> SetInternal(key, value, ApplicationData.Current.RoamingSettings.Values);
private static T GetInternal<T>(string key, IPropertySet collection, T defaultValue = default)
private static T GetInternal<T>(string key, IPropertySet collection, T defaultValue = default!)
{
if (collection.TryGetValue(key, out object value))
if (collection.TryGetValue(key, out object? value))
{
var stringValue = value?.ToString();
if (string.IsNullOrWhiteSpace(stringValue))
return defaultValue;
if (typeof(T).IsEnum)
return (T)Enum.Parse(typeof(T), stringValue);
@@ -40,7 +42,8 @@ public class ConfigurationService : IConfigurationService
return (T)(object)TimeSpan.Parse(stringValue);
}
return (T)Convert.ChangeType(stringValue, typeof(T));
var converted = Convert.ChangeType(stringValue, typeof(T));
return converted is T typed ? typed : defaultValue;
}
return defaultValue;
+1 -1
View File
@@ -119,7 +119,7 @@ public class DialogService : DialogServiceBase, IMailDialogService
await HandleDialogPresentationAsync(accountPicker);
return accountPicker.PickedAccount;
return accountPicker.PickedAccount ?? null!;
}
public async Task<AccountSignature> ShowSignatureEditorDialog(AccountSignature? signatureModel = null)
+23 -11
View File
@@ -40,7 +40,7 @@ public class DialogServiceBase : IDialogServiceBase
ApplicationResourceManager = applicationResourceManager;
}
protected XamlRoot GetXamlRoot()
protected XamlRoot? GetXamlRoot()
{
return WinoApplication.MainWindow?.Content?.XamlRoot;
}
@@ -54,7 +54,10 @@ public class DialogServiceBase : IDialogServiceBase
picker.FileTypeFilter.Add("*");
nint windowHandle = WindowNative.GetWindowHandle(WinoApplication.MainWindow);
var mainWindow = WinoApplication.MainWindow;
if (mainWindow == null) return string.Empty;
nint windowHandle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, windowHandle);
var folder = await picker.PickSingleFolderAsync();
@@ -94,7 +97,10 @@ public class DialogServiceBase : IDialogServiceBase
picker.FileTypeFilter.Add(filter.ToString());
}
nint windowHandle = WindowNative.GetWindowHandle(WinoApplication.MainWindow);
var mainWindow = WinoApplication.MainWindow;
if (mainWindow == null) return returnList;
nint windowHandle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, windowHandle);
var files = await picker.PickMultipleFilesAsync();
@@ -111,7 +117,7 @@ public class DialogServiceBase : IDialogServiceBase
return returnList;
}
private async Task<StorageFile> PickFileAsync(params object[] typeFilters)
private async Task<StorageFile?> PickFileAsync(params object[] typeFilters)
{
var picker = new FileOpenPicker
{
@@ -123,7 +129,10 @@ public class DialogServiceBase : IDialogServiceBase
picker.FileTypeFilter.Add(filter.ToString());
}
nint windowHandle = WindowNative.GetWindowHandle(WinoApplication.MainWindow);
var mainWindow = WinoApplication.MainWindow;
if (mainWindow == null) return null;
nint windowHandle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, windowHandle);
var file = await picker.PickSingleFileAsync();
@@ -174,7 +183,7 @@ public class DialogServiceBase : IDialogServiceBase
if (isDontAskEnabled && ConfigurationService.Get(dontAskAgainConfigurationKey, false)) return false;
var informationContainer = new CustomMessageDialogInformationContainer(title, description, icon.Value, isDontAskEnabled);
var informationContainer = new CustomMessageDialogInformationContainer(title, description, icon ?? WinoCustomMessageDialogIcon.Information, isDontAskEnabled);
var dialog = new ContentDialog
{
@@ -270,7 +279,10 @@ public class DialogServiceBase : IDialogServiceBase
picker.FileTypeFilter.Add("*");
nint windowHandle = WindowNative.GetWindowHandle(WinoApplication.MainWindow);
var mainWindow = WinoApplication.MainWindow;
if (mainWindow == null) return string.Empty;
nint windowHandle = WindowNative.GetWindowHandle(mainWindow);
InitializeWithWindow.Initialize(picker, windowHandle);
var pickedFolder = await picker.PickSingleFolderAsync();
@@ -307,10 +319,10 @@ public class DialogServiceBase : IDialogServiceBase
await HandleDialogPresentationAsync(dialog);
return dialog.Result;
return dialog.Result ?? null!;
}
public async Task<WebView2PrintSettingsModel> ShowPrintDialogAsync(WebView2PrintSettingsModel initialSettings = null)
public async Task<WebView2PrintSettingsModel> ShowPrintDialogAsync(WebView2PrintSettingsModel initialSettings = default!)
{
try
{
@@ -334,13 +346,13 @@ public class DialogServiceBase : IDialogServiceBase
// Return the settings if user clicked Print, otherwise null
return result == ContentDialogResult.Primary
? dialog.PrintSettings
: null;
: null!;
}
catch (Exception ex)
{
// Log the exception if logging is available
Log.Error(ex, "Error showing print dialog");
return null;
return null!;
}
}
}
+3 -3
View File
@@ -16,10 +16,10 @@ namespace Wino.Services;
public class NativeAppService : INativeAppService
{
private string _mimeMessagesFolder;
private string _editorBundlePath;
private string _mimeMessagesFolder = string.Empty;
private string _editorBundlePath = string.Empty;
public Func<IntPtr> GetCoreWindowHwnd { get; set; }
public Func<IntPtr> GetCoreWindowHwnd { get; set; } = static () => IntPtr.Zero;
public string GetWebAuthenticationBrokerUri()
{
@@ -100,7 +100,10 @@ public class NavigationService : NavigationServiceBase, INavigationService
if (frameType == NavigationReferenceFrame.ShellFrame) return shellWindow.GetMainFrame();
return WinoVisualTreeHelper.GetChildObject<Frame>(mainFrame.Content as UIElement, frameType.ToString());
var contentRoot = mainFrame.Content as UIElement;
if (contentRoot == null) return mainFrame;
return WinoVisualTreeHelper.GetChildObject<Frame>(contentRoot, frameType.ToString()) ?? mainFrame;
}
public bool ChangeApplicationMode(WinoApplicationMode mode)
@@ -17,7 +17,7 @@ public class NavigationServiceBase
};
}
public Type GetCurrentFrameType(ref Frame _frame)
public Type? GetCurrentFrameType(ref Frame _frame)
{
if (_frame != null && _frame.Content != null)
return _frame.Content.GetType();
+19 -9
View File
@@ -45,9 +45,9 @@ public class NewThemeService : INewThemeService
private static string _snowflakeThemeId = "e143ddde-2e28-4846-9d98-dad63d6505f1";
private static string _gardenThemeId = "698e4466-f88c-4799-9c61-f0ea1308ed49";
public event EventHandler<ApplicationElementTheme> ElementThemeChanged;
public event EventHandler<string> AccentColorChanged;
public event EventHandler<WindowBackdropType> BackdropChanged;
public event EventHandler<ApplicationElementTheme>? ElementThemeChanged;
public event EventHandler<string>? AccentColorChanged;
public event EventHandler<WindowBackdropType>? BackdropChanged;
private const string AccentColorKey = nameof(AccentColorKey);
private const string CurrentApplicationThemeKey = nameof(CurrentApplicationThemeKey);
@@ -125,7 +125,7 @@ public class NewThemeService : INewThemeService
}
}
private string accentColor;
private string accentColor = string.Empty;
public string AccentColor
{
@@ -218,7 +218,7 @@ public class NewThemeService : INewThemeService
try
{
Microsoft.UI.Xaml.Media.SystemBackdrop backdrop = backdropType switch
Microsoft.UI.Xaml.Media.SystemBackdrop? backdrop = backdropType switch
{
WindowBackdropType.Mica => new MicaBackdrop() { Kind = Microsoft.UI.Composition.SystemBackdrops.MicaKind.Base },
WindowBackdropType.MicaAlt => new MicaBackdrop() { Kind = Microsoft.UI.Composition.SystemBackdrops.MicaKind.BaseAlt },
@@ -385,7 +385,7 @@ public class NewThemeService : INewThemeService
return;
}
AppThemeBase applyingTheme = null;
AppThemeBase? applyingTheme = null;
var controlThemeList = new List<AppThemeBase>(preDefinedThemes);
@@ -416,13 +416,19 @@ public class NewThemeService : INewThemeService
}
}
if (applyingTheme == null)
{
Debug.WriteLine($"Theme with ID {currentApplicationThemeId} not found, skipping theme application");
return;
}
try
{
var existingThemeDictionary = _applicationResourceManager.GetLastResource();
if (existingThemeDictionary != null && existingThemeDictionary.TryGetValue("ThemeName", out object themeNameString))
if (existingThemeDictionary != null && existingThemeDictionary.TryGetValue("ThemeName", out object? themeNameString))
{
var themeName = themeNameString.ToString();
var themeName = themeNameString?.ToString();
// Applying different theme.
if (themeName != applyingTheme.ThemeName)
@@ -430,6 +436,10 @@ public class NewThemeService : INewThemeService
var resourceDictionaryContent = await applyingTheme.GetThemeResourceDictionaryContentAsync();
var resourceDictionary = XamlReader.Load(resourceDictionaryContent) as ResourceDictionary;
if (resourceDictionary == null)
{
return;
}
// Custom themes require special attention for background image because
// they share the same base theme resource dictionary.
@@ -561,7 +571,7 @@ public class NewThemeService : INewThemeService
return results;
}
private async Task<CustomThemeMetadata> GetCustomMetadataAsync(IStorageFile file)
private async Task<CustomThemeMetadata?> GetCustomMetadataAsync(IStorageFile file)
{
var fileContent = await FileIO.ReadTextAsync(file);
@@ -215,7 +215,12 @@ public class NotificationBuilder : INotificationBuilder
XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);
// Set the value of the badge in the XML to our number
XmlElement badgeElement = badgeXml.SelectSingleNode("/badge") as XmlElement;
XmlElement? badgeElement = badgeXml.SelectSingleNode("/badge") as XmlElement;
if (badgeElement == null)
{
badgeUpdater.Clear();
return;
}
badgeElement.SetAttribute("value", totalUnreadCount.ToString());
// Create the badge notification
@@ -17,20 +17,20 @@ public class PreferencesService(IConfigurationService configurationService) : Ob
{
private readonly IConfigurationService _configurationService = configurationService;
public event EventHandler<string> PreferenceChanged;
public event EventHandler<string>? PreferenceChanged;
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
PreferenceChanged?.Invoke(this, e.PropertyName);
PreferenceChanged?.Invoke(this, e.PropertyName ?? string.Empty);
}
private void SaveProperty(string propertyName, object value) => _configurationService.Set(propertyName, value);
private void SaveProperty(string propertyName, object? value) => _configurationService.Set(propertyName, value ?? string.Empty);
private void SetPropertyAndSave(string propertyName, object value)
private void SetPropertyAndSave(string propertyName, object? value)
{
_configurationService.Set(propertyName, value);
_configurationService.Set(propertyName, value ?? string.Empty);
OnPropertyChanged(propertyName);
Debug.WriteLine($"PreferencesService -> {propertyName}:{value?.ToString()}");
+15 -6
View File
@@ -24,10 +24,10 @@ namespace Wino.Mail.WinUI.Services;
public class PrintService : IPrintService
{
private TaskCompletionSource<PrintingResult> _taskCompletionSource;
private CanvasPrintDocument printDocument;
private PrintTask printTask;
private PdfDocument pdfDocument;
private TaskCompletionSource<PrintingResult>? _taskCompletionSource;
private CanvasPrintDocument? printDocument;
private PrintTask? printTask;
private PdfDocument? pdfDocument;
private List<CanvasBitmap> bitmaps = new();
private Vector2 largestBitmap;
@@ -41,7 +41,7 @@ public class PrintService : IPrintService
private int bitmapsPerPage;
private int pageCount = -1;
private PrintInformation _currentPrintInformation;
private PrintInformation? _currentPrintInformation;
public async Task<PrintingResult> PrintPdfFileAsync(string pdfFilePath, string printTitle)
{
@@ -125,6 +125,9 @@ public class PrintService : IPrintService
printTask = args.Request.CreatePrintTask(_currentPrintInformation.PDFTitle, (createPrintTaskArgs) =>
{
if (printDocument == null)
return;
createPrintTaskArgs.SetSource(printDocument);
});
@@ -191,6 +194,9 @@ public class PrintService : IPrintService
private async Task LoadPDFPageBitmapsAsync(CanvasPrintDocument sender)
{
if (pdfDocument == null)
return;
ClearBitmaps();
bitmaps ??= new List<CanvasBitmap>();
@@ -226,6 +232,9 @@ public class PrintService : IPrintService
{
var detailedOptions = PrintTaskOptionDetails.GetFromPrintTaskOptions(args.PrintTaskOptions);
if (pdfDocument == null)
return;
int pageCountToPrint = (int)pdfDocument.PageCount;
for (uint i = 1; i <= pageCountToPrint; ++i)
@@ -239,7 +248,7 @@ public class PrintService : IPrintService
private void DrawPdfPage(CanvasPrintDocument sender, CanvasDrawingSession ds, uint pageNumber)
{
if (bitmaps?.Count == 0) return;
if (bitmaps.Count == 0) return;
var cellAcross = new Vector2(cellSize.X, 0);
var cellDown = new Vector2(0, cellSize.Y);
@@ -17,7 +17,7 @@ public class SmimeCertificateService : ISmimeCertificateService
/// private key and at least one extension. The store is opened in read-only mode.</remarks>
/// <returns>An enumerable collection of <see cref="X509Certificate2"/> objects representing the personal certificates that
/// meet the specified criteria. If no matching certificates are found, the collection will be empty.</returns>
public IEnumerable<X509Certificate2> GetCertificates(StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser, string emailAddress = null)
public IEnumerable<X509Certificate2> GetCertificates(StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser, string? emailAddress = null)
{
using var store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.ReadOnly);
@@ -26,7 +26,7 @@ public class SmimeCertificateService : ISmimeCertificateService
}
public void ImportCertificate(string fileExtension, byte[] rawData, string password = null, StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser)
public void ImportCertificate(string fileExtension, byte[] rawData, string? password = null, StoreName storeName = StoreName.My, StoreLocation storeLocation = StoreLocation.CurrentUser)
{
X509Certificate2Collection collection = [];
@@ -198,7 +198,13 @@ public class StatePersistenceService : ObservableObject, IStatePersistanceServic
}
}
private void UpdateAppCoreWindowTitle() => WinoApplication.MainWindow.Title = CoreWindowTitle;
private void UpdateAppCoreWindowTitle()
{
if (WinoApplication.MainWindow != null)
{
WinoApplication.MainWindow.Title = CoreWindowTitle;
}
}
private static CalendarDisplayType EnsureValidCalendarDisplayType(CalendarDisplayType displayType)
{
+7 -7
View File
@@ -21,7 +21,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
private static readonly HttpClient _httpClient = new();
private bool _isInitialized = false;
private ConcurrentDictionary<string, (string graviton, string favicon)> _cache;
private ConcurrentDictionary<string, (string? graviton, string? favicon)> _cache = [];
private readonly ConcurrentDictionary<string, Task> _requests = [];
private static readonly List<string> _excludedFaviconDomains = [
@@ -43,7 +43,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
"rediffmail.com"
];
public async ValueTask<string> GetThumbnailAsync(string email, bool awaitLoad = false)
public async ValueTask<string?> GetThumbnailAsync(string email, bool awaitLoad = false)
{
if (string.IsNullOrWhiteSpace(email))
return null;
@@ -55,8 +55,8 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
{
var thumbnailsList = await _databaseService.Connection.Table<Thumbnail>().ToListAsync();
_cache = new ConcurrentDictionary<string, (string graviton, string favicon)>(
thumbnailsList.ToDictionary(x => x.Domain, x => (x.Gravatar, x.Favicon)));
_cache = new ConcurrentDictionary<string, (string? graviton, string? favicon)>(
thumbnailsList.ToDictionary(x => x.Domain, x => ((string?)x.Gravatar, (string?)x.Favicon)));
_isInitialized = true;
}
@@ -84,7 +84,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
await _databaseService.Connection.DeleteAllAsync<Thumbnail>();
}
private async ValueTask<(string gravatar, string favicon)> GetThumbnailInternal(string email, bool awaitLoad)
private async ValueTask<(string? gravatar, string? favicon)> GetThumbnailInternal(string email, bool awaitLoad)
{
if (_cache.TryGetValue(email, out var cached))
return cached;
@@ -136,7 +136,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
WeakReferenceMessenger.Default.Send(new ThumbnailAdded(email));
}
private static async Task<string> GetGravatarBase64(string email)
private static async Task<string?> GetGravatarBase64(string email)
{
try
{
@@ -156,7 +156,7 @@ public class ThumbnailService(IPreferencesService preferencesService, IDatabaseS
return null;
}
private static async Task<string> GetFaviconBase64(string email)
private static async Task<string?> GetFaviconBase64(string email)
{
try
{