稳定性提升
This commit is contained in:
lincube
2026-03-03 11:10:57 +08:00
parent 5dc2d680fb
commit 2d09c1aca2
22 changed files with 346 additions and 146 deletions

View File

@@ -92,7 +92,8 @@ public sealed class ComponentRegistry
MinWidthCells: 2, MinWidthCells: 2,
MinHeightCells: 4, MinHeightCells: 4,
AllowStatusBarPlacement: false, AllowStatusBarPlacement: false,
AllowDesktopPlacement: true), AllowDesktopPlacement: true,
ResizeMode: DesktopComponentResizeMode.Free),
new DesktopComponentDefinition( new DesktopComponentDefinition(
BuiltInComponentIds.DesktopBlackboardLandscape, BuiltInComponentIds.DesktopBlackboardLandscape,
"Blackboard Landscape", "Blackboard Landscape",
@@ -101,7 +102,8 @@ public sealed class ComponentRegistry
MinWidthCells: 4, MinWidthCells: 4,
MinHeightCells: 2, MinHeightCells: 2,
AllowStatusBarPlacement: false, AllowStatusBarPlacement: false,
AllowDesktopPlacement: true), AllowDesktopPlacement: true,
ResizeMode: DesktopComponentResizeMode.Free),
new DesktopComponentDefinition( new DesktopComponentDefinition(
BuiltInComponentIds.Date, BuiltInComponentIds.Date,
"Calendar", "Calendar",

View File

@@ -8,4 +8,5 @@ public sealed record DesktopComponentDefinition(
int MinWidthCells, int MinWidthCells,
int MinHeightCells, int MinHeightCells,
bool AllowStatusBarPlacement, bool AllowStatusBarPlacement,
bool AllowDesktopPlacement); bool AllowDesktopPlacement,
DesktopComponentResizeMode ResizeMode = DesktopComponentResizeMode.Proportional);

View File

@@ -0,0 +1,7 @@
namespace LanMontainDesktop.ComponentSystem;
public enum DesktopComponentResizeMode
{
Proportional = 0,
Free = 1
}

View File

@@ -69,7 +69,7 @@ public sealed class TimeZoneService
/// </summary> /// </summary>
public string GetTimeZoneDisplayName(TimeZoneInfo timeZone) public string GetTimeZoneDisplayName(TimeZoneInfo timeZone)
{ {
var offset = timeZone.BaseUtcOffset; var offset = timeZone.GetUtcOffset(DateTime.UtcNow);
var sign = offset >= TimeSpan.Zero ? "+" : "-"; var sign = offset >= TimeSpan.Zero ? "+" : "-";
var hours = Math.Abs(offset.Hours); var hours = Math.Abs(offset.Hours);
var minutes = Math.Abs(offset.Minutes); var minutes = Math.Abs(offset.Minutes);

View File

@@ -82,7 +82,7 @@ public sealed class WindowsStartMenuService
nameOverride ?? Path.GetFileName(folderPath), nameOverride ?? Path.GetFileName(folderPath),
relativePath); relativePath);
foreach (var subFolderPath in Directory.EnumerateDirectories(folderPath)) foreach (var subFolderPath in EnumerateDirectoriesSafe(folderPath))
{ {
var folderName = Path.GetFileName(subFolderPath); var folderName = Path.GetFileName(subFolderPath);
if (folderName.StartsWith(".", StringComparison.Ordinal)) if (folderName.StartsWith(".", StringComparison.Ordinal))
@@ -90,38 +90,76 @@ public sealed class WindowsStartMenuService
continue; continue;
} }
folder.Folders.Add(ScanFolder(subFolderPath, rootPath)); try
{
folder.Folders.Add(ScanFolder(subFolderPath, rootPath));
}
catch
{
// Skip unreadable branches but continue scanning siblings.
}
} }
foreach (var filePath in Directory.EnumerateFiles(folderPath)) foreach (var filePath in EnumerateFilesSafe(folderPath))
{ {
var extension = Path.GetExtension(filePath); try
if (!SupportedEntryExtensions.Contains(extension))
{ {
continue; var extension = Path.GetExtension(filePath);
} if (!SupportedEntryExtensions.Contains(extension))
{
continue;
}
var fileName = Path.GetFileNameWithoutExtension(filePath); var fileName = Path.GetFileNameWithoutExtension(filePath);
if (string.IsNullOrWhiteSpace(fileName)) if (string.IsNullOrWhiteSpace(fileName))
{ {
continue; continue;
} }
var normalizedName = fileName.Replace('_', ' ').Trim(); var normalizedName = fileName.Replace('_', ' ').Trim();
folder.Apps.Add(new StartMenuAppEntry folder.Apps.Add(new StartMenuAppEntry
{
DisplayName = normalizedName,
FilePath = filePath,
RelativePath = Path.GetRelativePath(rootPath, filePath),
IconPngBytes = OperatingSystem.IsWindows()
? WindowsIconService.TryGetIconPngBytes(filePath)
: null
});
}
catch
{ {
DisplayName = normalizedName, // Skip unreadable or invalid entries and continue.
FilePath = filePath, }
RelativePath = Path.GetRelativePath(rootPath, filePath),
IconPngBytes = OperatingSystem.IsWindows()
? WindowsIconService.TryGetIconPngBytes(filePath)
: null
});
} }
return folder; return folder;
} }
private static IEnumerable<string> EnumerateDirectoriesSafe(string folderPath)
{
try
{
return Directory.EnumerateDirectories(folderPath);
}
catch
{
return Array.Empty<string>();
}
}
private static IEnumerable<string> EnumerateFilesSafe(string folderPath)
{
try
{
return Directory.EnumerateFiles(folderPath);
}
catch
{
return Array.Empty<string>();
}
}
private static void MergeFolder(StartMenuFolderNode target, StartMenuFolderNode source) private static void MergeFolder(StartMenuFolderNode target, StartMenuFolderNode source)
{ {
var appPathSet = new HashSet<string>( var appPathSet = new HashSet<string>(

View File

@@ -45,16 +45,23 @@ public partial class AnalogClockWidget : UserControl, IDesktopComponentWidget, I
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
UpdateClock(); UpdateClock();
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e) private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{ {
InitializeDialIfNeeded(); InitializeDialIfNeeded();

View File

@@ -51,16 +51,23 @@ public partial class ClockWidget : UserControl, IDesktopComponentWidget, ITimeZo
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService != null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
UpdateClock(); UpdateClock();
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e) private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{ {
UpdateClock(); UpdateClock();

View File

@@ -109,16 +109,23 @@ public partial class DateWidget : UserControl, IDesktopComponentWidget, ITimeZon
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
UpdateDate(); UpdateDate();
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e) private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{ {
UpdateDate(); UpdateDate();

View File

@@ -10,7 +10,7 @@
<Border Background="{DynamicResource AdaptiveBackgroundBrush}" <Border Background="{DynamicResource AdaptiveBackgroundBrush}"
Padding="24"> Padding="24">
<StackPanel Spacing="16"> <StackPanel Spacing="16">
<TextBlock Text="日历组件设置" <TextBlock Text="Date Widget Settings"
FontSize="20" FontSize="20"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" /> Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" />

View File

@@ -37,16 +37,23 @@ public partial class HolidayCalendarWidget : UserControl, IDesktopComponentWidge
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
TriggerContentRefresh(); TriggerContentRefresh();
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e) private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{ {
TriggerContentRefresh(); TriggerContentRefresh();

View File

@@ -195,15 +195,22 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService) public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
{ {
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService; _weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;

View File

@@ -10,6 +10,7 @@ public interface IDesktopComponentWidget
public interface ITimeZoneAwareComponentWidget public interface ITimeZoneAwareComponentWidget
{ {
void SetTimeZoneService(TimeZoneService timeZoneService); void SetTimeZoneService(TimeZoneService timeZoneService);
void ClearTimeZoneService();
} }
public interface IWeatherInfoAwareComponentWidget public interface IWeatherInfoAwareComponentWidget

View File

@@ -99,16 +99,23 @@ public partial class LunarCalendarWidget : UserControl, IDesktopComponentWidget,
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
UpdateContent(); UpdateContent();
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e) private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{ {
UpdateContent(); UpdateContent();

View File

@@ -40,16 +40,23 @@ public partial class MonthCalendarWidget : UserControl, IDesktopComponentWidget,
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
UpdateCalendar(); UpdateCalendar();
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e) private void OnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{ {
UpdateCalendar(); UpdateCalendar();

View File

@@ -195,15 +195,22 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService) public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
{ {
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService; _weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;

View File

@@ -75,16 +75,23 @@ public partial class WeatherClockWidget : UserControl, IDesktopComponentWidget,
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
UpdateClockVisual(); UpdateClockVisual();
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService) public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
{ {
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService; _weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;

View File

@@ -137,15 +137,22 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, ITime
public void SetTimeZoneService(TimeZoneService timeZoneService) public void SetTimeZoneService(TimeZoneService timeZoneService)
{ {
if (_timeZoneService is not null) ClearTimeZoneService();
{
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
}
_timeZoneService = timeZoneService; _timeZoneService = timeZoneService;
_timeZoneService.TimeZoneChanged += OnTimeZoneChanged; _timeZoneService.TimeZoneChanged += OnTimeZoneChanged;
} }
public void ClearTimeZoneService()
{
if (_timeZoneService is null)
{
return;
}
_timeZoneService.TimeZoneChanged -= OnTimeZoneChanged;
_timeZoneService = null;
}
public void SetWeatherInfoService(IWeatherInfoService weatherInfoService) public void SetWeatherInfoService(IWeatherInfoService weatherInfoService)
{ {
_weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService; _weatherInfoService = weatherInfoService ?? DefaultWeatherInfoService;

View File

@@ -400,6 +400,7 @@ public partial class MainWindow
} }
ComponentLibraryWindow.IsVisible = false; ComponentLibraryWindow.IsVisible = false;
ClearComponentLibraryPreviewControls();
var shouldReopenSettings = reopenSettings && _reopenSettingsAfterComponentLibraryClose; var shouldReopenSettings = reopenSettings && _reopenSettingsAfterComponentLibraryClose;
_reopenSettingsAfterComponentLibraryClose = false; _reopenSettingsAfterComponentLibraryClose = false;
@@ -661,7 +662,8 @@ public partial class MainWindow
return; return;
} }
// 娴犲海缍夐弽闂磋厬缁夊娅庣紒鍕 ClearTimeZoneServiceBindings(_selectedDesktopComponentHost);
if (_desktopPageComponentGrids.TryGetValue(placement.PageIndex, out var pageGrid)) if (_desktopPageComponentGrids.TryGetValue(placement.PageIndex, out var pageGrid))
{ {
pageGrid.Children.Remove(_selectedDesktopComponentHost); pageGrid.Children.Remove(_selectedDesktopComponentHost);
@@ -748,7 +750,7 @@ public partial class MainWindow
RebuildDesktopGrid(); RebuildDesktopGrid();
PersistSettings(); PersistSettings();
// 閺囧瓨鏌婇崝銊︹偓浣锋崲閸斺剝鐖弰鍓с仛 // Refresh taskbar actions after page count changes.
ApplyTaskbarActionVisibility(GetCurrentTaskbarContext()); ApplyTaskbarActionVisibility(GetCurrentTaskbarContext());
} }
@@ -763,6 +765,11 @@ public partial class MainWindow
.Where(p => p.PageIndex == _currentDesktopSurfaceIndex) .Where(p => p.PageIndex == _currentDesktopSurfaceIndex)
.ToList(); .ToList();
if (_desktopPageComponentGrids.TryGetValue(_currentDesktopSurfaceIndex, out var pageGrid))
{
ClearTimeZoneServiceBindings(pageGrid.Children.OfType<Control>().ToList());
}
foreach (var placement in placementsToRemove) foreach (var placement in placementsToRemove)
{ {
_desktopComponentPlacements.Remove(placement); _desktopComponentPlacements.Remove(placement);
@@ -770,7 +777,7 @@ public partial class MainWindow
_desktopPageCount = Math.Clamp(_desktopPageCount - 1, MinDesktopPageCount, MaxDesktopPageCount); _desktopPageCount = Math.Clamp(_desktopPageCount - 1, MinDesktopPageCount, MaxDesktopPageCount);
// 鐠嬪啯鏆hぐ鎾冲妞ょ敻娼扮槐銏犵穿 // Clamp current page index to valid range after deletion.
_currentDesktopSurfaceIndex = Math.Clamp(_currentDesktopSurfaceIndex, 0, _desktopPageCount - 1); _currentDesktopSurfaceIndex = Math.Clamp(_currentDesktopSurfaceIndex, 0, _desktopPageCount - 1);
// Update remaining page indices after deletion. // Update remaining page indices after deletion.
@@ -785,7 +792,7 @@ public partial class MainWindow
RebuildDesktopGrid(); RebuildDesktopGrid();
PersistSettings(); PersistSettings();
// 閺囧瓨鏌婇崝銊︹偓浣锋崲閸斺剝鐖弰鍓с仛 // Refresh taskbar actions after page count changes.
ApplyTaskbarActionVisibility(GetCurrentTaskbarContext()); ApplyTaskbarActionVisibility(GetCurrentTaskbarContext());
} }
@@ -842,6 +849,7 @@ public partial class MainWindow
return; return;
} }
ClearTimeZoneServiceBindings(pageGrid.Children.OfType<Control>().ToList());
pageGrid.Children.Clear(); pageGrid.Children.Clear();
var maxColumns = pageGrid.ColumnDefinitions.Count; var maxColumns = pageGrid.ColumnDefinitions.Count;
@@ -1062,6 +1070,11 @@ public partial class MainWindow
runtimeDescriptor.Definition, runtimeDescriptor.Definition,
span.WidthCells, span.WidthCells,
span.HeightCells); span.HeightCells);
if (runtimeDescriptor.Definition.ResizeMode == DesktopComponentResizeMode.Free)
{
return normalized;
}
return NormalizeAspectRatioForComponent(componentId, normalized); return NormalizeAspectRatioForComponent(componentId, normalized);
} }
@@ -1070,6 +1083,16 @@ public partial class MainWindow
(Math.Max(1, span.WidthCells), Math.Max(1, span.HeightCells))); (Math.Max(1, span.WidthCells), Math.Max(1, span.HeightCells)));
} }
private DesktopComponentResizeMode GetComponentResizeMode(string componentId)
{
if (_componentRuntimeRegistry.TryGetDescriptor(componentId, out var runtimeDescriptor))
{
return runtimeDescriptor.Definition.ResizeMode;
}
return DesktopComponentResizeMode.Proportional;
}
private static (int WidthCells, int HeightCells) NormalizeAspectRatioForComponent( private static (int WidthCells, int HeightCells) NormalizeAspectRatioForComponent(
string componentId, string componentId,
(int WidthCells, int HeightCells) span) (int WidthCells, int HeightCells) span)
@@ -1196,6 +1219,30 @@ public partial class MainWindow
return null; return null;
} }
private static void ClearTimeZoneServiceBindings(IEnumerable<Control> roots)
{
foreach (var root in roots)
{
ClearTimeZoneServiceBindings(root);
}
}
private static void ClearTimeZoneServiceBindings(Control root)
{
if (root is ITimeZoneAwareComponentWidget timeZoneAwareRoot)
{
timeZoneAwareRoot.ClearTimeZoneService();
}
foreach (var descendant in root.GetVisualDescendants())
{
if (descendant is ITimeZoneAwareComponentWidget timeZoneAwareChild)
{
timeZoneAwareChild.ClearTimeZoneService();
}
}
}
private static Border? TryGetResizeHandle(Border host) private static Border? TryGetResizeHandle(Border host)
{ {
if (host.Child is Grid hostChrome) if (host.Child is Grid hostChrome)
@@ -1257,6 +1304,7 @@ public partial class MainWindow
CancelDesktopComponentResize(restoreOriginalSpan: true); CancelDesktopComponentResize(restoreOriginalSpan: true);
ClearDesktopComponentSelection(); ClearDesktopComponentSelection();
UpdateDesktopComponentHostEditState(); UpdateDesktopComponentHostEditState();
ClearComponentLibraryPreviewControls();
UpdateComponentLibraryLayout(_currentDesktopCellSize); UpdateComponentLibraryLayout(_currentDesktopCellSize);
} }
@@ -1615,36 +1663,52 @@ public partial class MainWindow
var deltaX = pointerInViewport.X - _desktopComponentResize.StartPointerInViewport.X; var deltaX = pointerInViewport.X - _desktopComponentResize.StartPointerInViewport.X;
var deltaY = pointerInViewport.Y - _desktopComponentResize.StartPointerInViewport.Y; var deltaY = pointerInViewport.Y - _desktopComponentResize.StartPointerInViewport.Y;
var widthScale = (_desktopComponentResize.StartWidthCells + deltaX / pitch) / _desktopComponentResize.StartWidthCells; int widthCells;
var heightScale = (_desktopComponentResize.StartHeightCells + deltaY / pitch) / _desktopComponentResize.StartHeightCells; int heightCells;
if (GetComponentResizeMode(_desktopComponentResize.ComponentId) == DesktopComponentResizeMode.Free)
var proposedScale = Math.Max(widthScale, heightScale);
var minScale = Math.Max(
(double)_desktopComponentResize.MinWidthCells / _desktopComponentResize.StartWidthCells,
(double)_desktopComponentResize.MinHeightCells / _desktopComponentResize.StartHeightCells);
var maxScale = Math.Min(
(double)_desktopComponentResize.MaxWidthCells / _desktopComponentResize.StartWidthCells,
(double)_desktopComponentResize.MaxHeightCells / _desktopComponentResize.StartHeightCells);
if (double.IsNaN(proposedScale) || double.IsInfinity(proposedScale))
{ {
proposedScale = minScale; widthCells = Math.Clamp(
(int)Math.Round(_desktopComponentResize.StartWidthCells + deltaX / pitch),
_desktopComponentResize.MinWidthCells,
_desktopComponentResize.MaxWidthCells);
heightCells = Math.Clamp(
(int)Math.Round(_desktopComponentResize.StartHeightCells + deltaY / pitch),
_desktopComponentResize.MinHeightCells,
_desktopComponentResize.MaxHeightCells);
} }
else
if (maxScale < minScale)
{ {
maxScale = minScale; var widthScale = (_desktopComponentResize.StartWidthCells + deltaX / pitch) / _desktopComponentResize.StartWidthCells;
} var heightScale = (_desktopComponentResize.StartHeightCells + deltaY / pitch) / _desktopComponentResize.StartHeightCells;
var scale = Math.Clamp(proposedScale, minScale, maxScale); var proposedScale = Math.Max(widthScale, heightScale);
var widthCells = Math.Clamp( var minScale = Math.Max(
(int)Math.Round(_desktopComponentResize.StartWidthCells * scale), (double)_desktopComponentResize.MinWidthCells / _desktopComponentResize.StartWidthCells,
_desktopComponentResize.MinWidthCells, (double)_desktopComponentResize.MinHeightCells / _desktopComponentResize.StartHeightCells);
_desktopComponentResize.MaxWidthCells); var maxScale = Math.Min(
var heightCells = Math.Clamp( (double)_desktopComponentResize.MaxWidthCells / _desktopComponentResize.StartWidthCells,
(int)Math.Round(_desktopComponentResize.StartHeightCells * scale), (double)_desktopComponentResize.MaxHeightCells / _desktopComponentResize.StartHeightCells);
_desktopComponentResize.MinHeightCells,
_desktopComponentResize.MaxHeightCells); if (double.IsNaN(proposedScale) || double.IsInfinity(proposedScale))
{
proposedScale = minScale;
}
if (maxScale < minScale)
{
maxScale = minScale;
}
var scale = Math.Clamp(proposedScale, minScale, maxScale);
widthCells = Math.Clamp(
(int)Math.Round(_desktopComponentResize.StartWidthCells * scale),
_desktopComponentResize.MinWidthCells,
_desktopComponentResize.MaxWidthCells);
heightCells = Math.Clamp(
(int)Math.Round(_desktopComponentResize.StartHeightCells * scale),
_desktopComponentResize.MinHeightCells,
_desktopComponentResize.MaxHeightCells);
}
var normalized = NormalizeComponentCellSpan(_desktopComponentResize.ComponentId, (widthCells, heightCells)); var normalized = NormalizeComponentCellSpan(_desktopComponentResize.ComponentId, (widthCells, heightCells));
widthCells = Math.Clamp(normalized.WidthCells, _desktopComponentResize.MinWidthCells, _desktopComponentResize.MaxWidthCells); widthCells = Math.Clamp(normalized.WidthCells, _desktopComponentResize.MinWidthCells, _desktopComponentResize.MaxWidthCells);
@@ -2213,6 +2277,7 @@ public partial class MainWindow
_componentLibraryActiveComponents = category.Components; _componentLibraryActiveComponents = category.Components;
var componentCount = _componentLibraryActiveComponents.Count; var componentCount = _componentLibraryActiveComponents.Count;
ClearTimeZoneServiceBindings(ComponentLibraryComponentPagesContainer.Children.OfType<Control>().ToList());
ComponentLibraryComponentPagesContainer.Children.Clear(); ComponentLibraryComponentPagesContainer.Children.Clear();
ComponentLibraryComponentPagesContainer.RowDefinitions.Clear(); ComponentLibraryComponentPagesContainer.RowDefinitions.Clear();
ComponentLibraryComponentPagesContainer.ColumnDefinitions.Clear(); ComponentLibraryComponentPagesContainer.ColumnDefinitions.Clear();
@@ -2374,6 +2439,19 @@ public partial class MainWindow
UpdateComponentLibraryComponentNavigationButtons(); UpdateComponentLibraryComponentNavigationButtons();
} }
private void ClearComponentLibraryPreviewControls()
{
if (ComponentLibraryComponentPagesContainer is null)
{
return;
}
ClearTimeZoneServiceBindings(ComponentLibraryComponentPagesContainer.Children.OfType<Control>().ToList());
ComponentLibraryComponentPagesContainer.Children.Clear();
ComponentLibraryComponentPagesContainer.RowDefinitions.Clear();
ComponentLibraryComponentPagesContainer.ColumnDefinitions.Clear();
}
private string GetLocalizedComponentDisplayName(DesktopComponentRuntimeDescriptor descriptor) private string GetLocalizedComponentDisplayName(DesktopComponentRuntimeDescriptor descriptor)
{ {
return L(descriptor.DisplayNameLocalizationKey, descriptor.Definition.DisplayName); return L(descriptor.DisplayNameLocalizationKey, descriptor.Definition.DisplayName);

View File

@@ -127,6 +127,7 @@ public partial class MainWindow
DesktopPagesContainer.RowDefinitions.Clear(); DesktopPagesContainer.RowDefinitions.Clear();
DesktopPagesContainer.RowDefinitions.Add(new RowDefinition(new GridLength(pageHeight, GridUnitType.Pixel))); DesktopPagesContainer.RowDefinitions.Add(new RowDefinition(new GridLength(pageHeight, GridUnitType.Pixel)));
DesktopPagesContainer.ColumnDefinitions.Clear(); DesktopPagesContainer.ColumnDefinitions.Clear();
ClearTimeZoneServiceBindings(DesktopPagesContainer.Children.OfType<Control>().ToList());
DesktopPagesContainer.Children.Clear(); DesktopPagesContainer.Children.Clear();
DesktopPagesContainer.Width = pageWidth * _desktopPageCount; DesktopPagesContainer.Width = pageWidth * _desktopPageCount;
DesktopPagesContainer.Height = pageHeight; DesktopPagesContainer.Height = pageHeight;

View File

@@ -86,20 +86,22 @@ public partial class MainWindow
WallpaperPreviewBackButtonTextBlock.Text = L("button.back_to_windows", "Back to Windows"); WallpaperPreviewBackButtonTextBlock.Text = L("button.back_to_windows", "Back to Windows");
ToolTip.SetTip(BackToWindowsButton, L("tooltip.back_to_windows", "Back to Windows")); ToolTip.SetTip(BackToWindowsButton, L("tooltip.back_to_windows", "Back to Windows"));
OpenComponentLibraryTextBlock.Text = L("button.component_library", "编辑桌面"); OpenComponentLibraryTextBlock.Text = L("button.component_library", "Edit Desktop");
WallpaperPreviewComponentLibraryTextBlock.Text = L("button.component_library", "编辑桌面"); WallpaperPreviewComponentLibraryTextBlock.Text = L("button.component_library", "Edit Desktop");
GridPreviewComponentLibraryTextBlock.Text = L("button.component_library", "编辑桌面"); GridPreviewComponentLibraryTextBlock.Text = L("button.component_library", "Edit Desktop");
ToolTip.SetTip(OpenComponentLibraryButton, L("tooltip.component_library", "编辑桌面")); ToolTip.SetTip(OpenComponentLibraryButton, L("tooltip.component_library", "Edit Desktop"));
ComponentLibraryTitleTextBlock.Text = L("component_library.title", "小组件"); ComponentLibraryTitleTextBlock.Text = L("component_library.title", "Widgets");
ToolTip.SetTip(CloseComponentLibraryButton, L("common.close", "Close")); ToolTip.SetTip(CloseComponentLibraryButton, L("common.close", "Close"));
ComponentLibraryEmptyTextBlock.Text = L( ComponentLibraryEmptyTextBlock.Text = L(
"component_library.empty", "component_library.empty",
"Swipe to pick a category, tap to open, then drag a widget onto the desktop."); "Swipe to pick a category, tap to open, then drag a widget onto the desktop.");
LauncherTitleTextBlock.Text = L("launcher.title", "应用启动台"); LauncherTitleTextBlock.Text = L("launcher.title", "App Launcher");
LauncherSubtitleTextBlock.Text = L("launcher.subtitle", "按 Windows 开始菜单结构显示所有应用与文件夹"); LauncherSubtitleTextBlock.Text = L(
ToolTip.SetTip(LauncherFolderBackButton, L("common.back", "返回")); "launcher.subtitle",
ToolTip.SetTip(LauncherFolderCloseButton, L("common.close", "关闭")); "Displays all apps and folders based on the Windows Start menu structure.");
ToolTip.SetTip(LauncherFolderBackButton, L("common.back", "Back"));
ToolTip.SetTip(LauncherFolderCloseButton, L("common.close", "Close"));
SettingsNavHeaderTextBlock.Text = L("settings.nav_header", "Settings"); SettingsNavHeaderTextBlock.Text = L("settings.nav_header", "Settings");
SettingsNavWallpaperTextBlock.Text = L("settings.nav.wallpaper", "Wallpaper"); SettingsNavWallpaperTextBlock.Text = L("settings.nav.wallpaper", "Wallpaper");
@@ -109,11 +111,13 @@ public partial class MainWindow
SettingsNavWeatherTextBlock.Text = L("settings.nav.weather", "Weather"); SettingsNavWeatherTextBlock.Text = L("settings.nav.weather", "Weather");
SettingsNavRegionTextBlock.Text = L("settings.nav.region", "Region"); SettingsNavRegionTextBlock.Text = L("settings.nav.region", "Region");
WallpaperPanelTitleTextBlock.Text = L("settings.wallpaper.title", "个性化我们的背景"); WallpaperPanelTitleTextBlock.Text = L("settings.wallpaper.title", "Personalize your wallpaper");
WallpaperPlacementSettingsExpander.Header = L("settings.wallpaper.placement_label", "选择契合度"); WallpaperPlacementSettingsExpander.Header = L("settings.wallpaper.placement_label", "Placement");
WallpaperPlacementSettingsExpander.Description = L("settings.wallpaper.placement_desc", "调整图像在桌面上的填充方式。"); WallpaperPlacementSettingsExpander.Description = L(
PickWallpaperButton.Content = L("settings.wallpaper.pick_button", "浏览照片"); "settings.wallpaper.placement_desc",
ClearWallpaperButton.Content = L("settings.wallpaper.clear_button", "重置"); "Adjust how the image fits on the desktop.");
PickWallpaperButton.Content = L("settings.wallpaper.pick_button", "Browse");
ClearWallpaperButton.Content = L("settings.wallpaper.clear_button", "Reset");
GridPanelTitleTextBlock.Text = L("settings.grid.title", "Grid Layout"); GridPanelTitleTextBlock.Text = L("settings.grid.title", "Grid Layout");
GridSpacingPresetLabelTextBlock.Text = L("settings.grid.spacing_label", "Grid Spacing"); GridSpacingPresetLabelTextBlock.Text = L("settings.grid.spacing_label", "Grid Spacing");
@@ -265,7 +269,7 @@ public partial class MainWindow
private string GetLocalizedTimeZoneDisplayName(TimeZoneInfo timeZone) private string GetLocalizedTimeZoneDisplayName(TimeZoneInfo timeZone)
{ {
var offset = timeZone.BaseUtcOffset; var offset = timeZone.GetUtcOffset(DateTime.UtcNow);
var sign = offset >= TimeSpan.Zero ? "+" : "-"; var sign = offset >= TimeSpan.Zero ? "+" : "-";
var hours = Math.Abs(offset.Hours); var hours = Math.Abs(offset.Hours);
var minutes = Math.Abs(offset.Minutes); var minutes = Math.Abs(offset.Minutes);

View File

@@ -476,7 +476,7 @@
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
Margin="0,0,0,24" Margin="0,0,0,24"
Text="涓€у寲鎮ㄧ殑鑳屾櫙" /> Text="Personalize Wallpaper" />
<!-- Left Column: Monitor Preview --> <!-- Left Column: Monitor Preview -->
<Border x:Name="WallpaperPreviewHost" <Border x:Name="WallpaperPreviewHost"
@@ -563,11 +563,11 @@
FontWeight="Medium" FontWeight="Medium"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
TextTrimming="CharacterEllipsis" TextTrimming="CharacterEllipsis"
Text="鏈€夋嫨鏂囦欢" /> Text="No file selected" />
<TextBlock x:Name="WallpaperStatusTextBlock" <TextBlock x:Name="WallpaperStatusTextBlock"
FontSize="12" FontSize="12"
Foreground="{DynamicResource AdaptiveTextMutedBrush}" Foreground="{DynamicResource AdaptiveTextMutedBrush}"
Text="灏辩华" /> Text="Ready" />
</StackPanel> </StackPanel>
<Separator Background="{DynamicResource SurfaceStrokeColorDefaultBrush}" Height="1" Margin="0,8" /> <Separator Background="{DynamicResource SurfaceStrokeColorDefaultBrush}" Height="1" Margin="0,8" />
@@ -581,13 +581,13 @@
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Padding="0,10" Padding="0,10"
Click="OnPickWallpaperClick" Click="OnPickWallpaperClick"
Content="娴忚鐓х墖" /> Content="Browse" />
<Button x:Name="ClearWallpaperButton" <Button x:Name="ClearWallpaperButton"
Grid.Column="1" Grid.Column="1"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Padding="0,10" Padding="0,10"
Click="OnClearWallpaperClick" Click="OnClearWallpaperClick"
Content="閲嶇疆" /> Content="Reset" />
</Grid> </Grid>
<Border Classes="settings-expander-shell"> <Border Classes="settings-expander-shell">
@@ -695,7 +695,7 @@
<StackPanel Grid.Row="1" Grid.Column="1" <StackPanel Grid.Row="1" Grid.Column="1"
Margin="16,0,0,0" Margin="16,0,0,0"
Spacing="16"> Spacing="16">
<TextBlock Text="绔栨帓鏍兼暟" FontSize="16" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" /> <TextBlock Text="Rows" FontSize="16" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" />
<Grid ColumnDefinitions="*,Auto" ColumnSpacing="12"> <Grid ColumnDefinitions="*,Auto" ColumnSpacing="12">
<Slider x:Name="GridSizeSlider" <Slider x:Name="GridSizeSlider"
@@ -754,7 +754,7 @@
<TextBlock x:Name="GridEdgeInsetComputedPxTextBlock" <TextBlock x:Name="GridEdgeInsetComputedPxTextBlock"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="鈮?0 px" /> Text=">= 0 px" />
<Button x:Name="ApplyGridButton" <Button x:Name="ApplyGridButton"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
@@ -1005,15 +1005,15 @@
Unchecked="OnStatusBarClockUnchecked" /> Unchecked="OnStatusBarClockUnchecked" />
</ui:SettingsExpander.Footer> </ui:SettingsExpander.Footer>
<StackPanel Margin="0,8,0,0" Spacing="12"> <StackPanel Margin="0,8,0,0" Spacing="12">
<TextBlock Text="鏄剧ず鏍煎紡" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" /> <TextBlock Text="Display Format" FontSize="14" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" />
<StackPanel Orientation="Horizontal" Spacing="8"> <StackPanel Orientation="Horizontal" Spacing="8">
<RadioButton x:Name="ClockFormatHMSSRadio" <RadioButton x:Name="ClockFormatHMSSRadio"
Content="鏃跺垎绉?(HH:mm:ss)" Content="Time with seconds (HH:mm:ss)"
GroupName="ClockFormat" GroupName="ClockFormat"
Checked="OnClockFormatChanged" Checked="OnClockFormatChanged"
Tag="Hms" /> Tag="Hms" />
<RadioButton x:Name="ClockFormatHMRadio" <RadioButton x:Name="ClockFormatHMRadio"
Content="鏃跺垎 (HH:mm)" Content="Time (HH:mm)"
GroupName="ClockFormat" GroupName="ClockFormat"
Checked="OnClockFormatChanged" Checked="OnClockFormatChanged"
Tag="Hm" /> Tag="Hm" />
@@ -1070,7 +1070,7 @@
<TextBlock x:Name="StatusBarSpacingComputedPxTextBlock" <TextBlock x:Name="StatusBarSpacingComputedPxTextBlock"
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
Text="鈮?0 px" /> Text=">= 0 px" />
</StackPanel> </StackPanel>
</ui:SettingsExpander> </ui:SettingsExpander>
</Border> </Border>
@@ -1274,19 +1274,19 @@
</Border> </Border>
</StackPanel> </StackPanel>
<StackPanel x:Name="AboutSettingsPanel" IsVisible="False" Spacing="20"> <StackPanel x:Name="AboutSettingsPanel" IsVisible="False" Spacing="20">
<TextBlock x:Name="AboutPanelTitleTextBlock" FontSize="24" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" Text="鍏充簬" /> <TextBlock x:Name="AboutPanelTitleTextBlock" FontSize="24" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" Text="About" />
<Border Background="{DynamicResource AdaptiveSurfaceRaisedBrush}" CornerRadius="{DynamicResource DesignCornerRadiusMd}" Padding="20"> <Border Background="{DynamicResource AdaptiveSurfaceRaisedBrush}" CornerRadius="{DynamicResource DesignCornerRadiusMd}" Padding="20">
<StackPanel Spacing="12"> <StackPanel Spacing="12">
<TextBlock Text="LanMontainDesktop" FontSize="20" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" /> <TextBlock Text="LanMontainDesktop" FontSize="20" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" />
<TextBlock Text="Modern desktop shell experience." FontSize="13" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" /> <TextBlock Text="Modern desktop shell experience." FontSize="13" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
<Separator Background="{DynamicResource AdaptiveButtonBorderBrush}" Margin="0,8" /> <Separator Background="{DynamicResource AdaptiveButtonBorderBrush}" Margin="0,8" />
<TextBlock x:Name="VersionTextBlock" Text="鐗堟湰鍙? 1.0.0" FontSize="13" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" /> <TextBlock x:Name="VersionTextBlock" Text="Version: 1.0.0" FontSize="13" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" />
<TextBlock x:Name="CodeNameTextBlock" Text="鐗堟湰浠e彿: Administrate" FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveAccentBrush}" /> <TextBlock x:Name="CodeNameTextBlock" Text="Code Name: Administrate" FontSize="13" FontWeight="SemiBold" Foreground="{DynamicResource AdaptiveAccentBrush}" />
<TextBlock x:Name="FontInfoTextBlock" Text="字体: MiSans" FontSize="12" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" /> <TextBlock x:Name="FontInfoTextBlock" Text="Font: MiSans" FontSize="12" Foreground="{DynamicResource AdaptiveTextSecondaryBrush}" />
</StackPanel> </StackPanel>
</Border> </Border>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Border> </Border>
</Grid> </Grid>
@@ -1314,7 +1314,7 @@
CornerRadius="36,36,0,0" CornerRadius="36,36,0,0"
Padding="16,12"> Padding="16,12">
<Grid ColumnDefinitions="*,Auto"> <Grid ColumnDefinitions="*,Auto">
<TextBlock Text="缁勪欢璁剧疆" <TextBlock Text="Component Settings"
FontSize="16" FontSize="16"
FontWeight="SemiBold" FontWeight="SemiBold"
Foreground="White" Foreground="White"

View File

@@ -795,7 +795,7 @@ public partial class MainWindow : Window
var spacingPx = Math.Max(0, cellSize) * (percent / 100d); var spacingPx = Math.Max(0, cellSize) * (percent / 100d);
StatusBarSpacingComputedPxTextBlock.Text = Lf( StatusBarSpacingComputedPxTextBlock.Text = Lf(
"settings.status_bar.spacing_custom_px_format", "settings.status_bar.spacing_custom_px_format",
"鈮?{0:F1}px", ">= {0:F1}px",
spacingPx); spacingPx);
} }
@@ -863,13 +863,11 @@ public partial class MainWindow : Window
var shortSidePx = Math.Max(1, Math.Min(hostWidth, hostHeight)); var shortSidePx = Math.Max(1, Math.Min(hostWidth, hostHeight));
var baseCell = shortSidePx / cells; var baseCell = shortSidePx / cells;
// --- 姣斾緥鍖栫暀鐧?(Proportional Inset) --- // Proportional inset based on user percentage selection.
// 鍏佽鐢ㄦ埛鐧惧垎姣旇皟鑺傦紝浣嗚瀹氭洿鍚堢悊鐨勫熀鍑嗗拰闄愬埗
var clampedPercent = Math.Clamp(insetPercent, MinEdgeInsetPercent, MaxEdgeInsetPercent); var clampedPercent = Math.Clamp(insetPercent, MinEdgeInsetPercent, MaxEdgeInsetPercent);
var insetRatio = clampedPercent / 100d; var insetRatio = clampedPercent / 100d;
// 纭繚鏈€灏忕暀鐧借兘瀹圭撼涓€瀹氱殑闃村奖鎵╁睍 // Keep inset within a practical visual range.
// 鍏佽 0 杈硅窛锛屾渶澶т笂闄愮淮鎸?80px
return Math.Clamp(baseCell * insetRatio, 0, 80); return Math.Clamp(baseCell * insetRatio, 0, 80);
} }
@@ -1282,7 +1280,7 @@ public partial class MainWindow : Window
}; };
TimeZoneComboBox.Items.Add(item); TimeZoneComboBox.Items.Add(item);
// 閫変腑褰撳墠鏃跺尯 // Select current time zone.
if (tz.Id == _timeZoneService.CurrentTimeZone.Id) if (tz.Id == _timeZoneService.CurrentTimeZone.Id)
{ {
TimeZoneComboBox.SelectedItem = item; TimeZoneComboBox.SelectedItem = item;