Add time zones settings panel

This commit is contained in:
2024-10-04 17:32:10 -04:00
parent 4751ae476d
commit 50fd78a3c3
11 changed files with 657 additions and 37 deletions

View File

@@ -0,0 +1,83 @@
<Window x:Class="WorldClockStatusWindow.SettingsWindow.TimeZoneWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:properties="clr-namespace:WorldClockStatusWindow.Properties"
xmlns:worldClockStatusWindow="clr-namespace:WorldClockStatusWindow"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DataContext="{d:DesignInstance Type=worldClockStatusWindow:TimeZoneEntry}"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:windows="clr-namespace:ChrisKaczor.Wpf.Windows;assembly=ChrisKaczor.Wpf.Windows.CategoryWindow"
mc:Ignorable="d"
Title="TimeZoneWindow"
ResizeMode="NoResize"
SizeToContent="Height"
Width="450"
WindowStartupLocation="CenterOwner"
Icon="/WorldClockStatusWindow;component/Resources/Application.ico"
FocusManager.FocusedElement="{Binding ElementName=LabelTextBox}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.FlatButton.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/light.cobalt.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Margin="0,4"
windows:Spacing.Vertical="8">
<TextBox Name="LabelTextBox"
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.LabelColumnHeader}"
mah:TextBoxHelper.SelectAllOnFocus="True"
Text="{Binding Path=Label, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
<ComboBox Name="TimeZoneComboBox"
DisplayMemberPath="DisplayName"
SelectedValuePath="Id"
SelectedValue="{Binding Path=TimeZoneId}"
VirtualizingPanel.IsVirtualizing="False"
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.TimeZoneColumnHeader}" />
</StackPanel>
<StackPanel Grid.Column="0"
Grid.Row="1"
Orientation="Horizontal"
Margin="0,5,0,0"
HorizontalAlignment="Right">
<Button Content="{x:Static properties:Resources.OkayButton}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="75"
Margin="0,0,5,0"
IsDefault="True"
Click="HandleOkayButtonClick">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Text.Length, ElementName=LabelTextBox}"
Value="0">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Content="{x:Static properties:Resources.CancelButton}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="75"
IsCancel="True" />
</StackPanel>
</Grid>
</Window>

View File

@@ -0,0 +1,43 @@
using ChrisKaczor.Wpf.Validation;
using System;
using System.Windows;
namespace WorldClockStatusWindow.SettingsWindow;
public partial class TimeZoneWindow
{
public TimeZoneWindow()
{
InitializeComponent();
}
public bool? Display(TimeZoneEntry timeZoneEntry, Window owner)
{
DataContext = timeZoneEntry;
TimeZoneComboBox.ItemsSource = TimeZoneInfo.GetSystemTimeZones();
Title = string.IsNullOrWhiteSpace(timeZoneEntry.Label) ? Properties.Resources.TimeZoneWindowAdd : Properties.Resources.TimeZoneWindowEdit;
Owner = owner;
return ShowDialog();
}
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
if (!this.IsValid())
return;
var timeZoneEntry = (TimeZoneEntry)DataContext;
if (!Data.TimeZoneEntries.Contains(timeZoneEntry))
Data.TimeZoneEntries.Add(timeZoneEntry);
Data.Save();
DialogResult = true;
Close();
}
}

View File

@@ -0,0 +1,90 @@
<windows:CategoryPanelBase x:Class="WorldClockStatusWindow.SettingsWindow.TimeZonesSettingsPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:properties="clr-namespace:WorldClockStatusWindow.Properties"
xmlns:worldClockStatusWindow="clr-namespace:WorldClockStatusWindow"
xmlns:windows="clr-namespace:ChrisKaczor.Wpf.Windows;assembly=ChrisKaczor.Wpf.Windows.CategoryWindow"
xmlns:controls="clr-namespace:ChrisKaczor.Wpf.Controls;assembly=ChrisKaczor.Wpf.Controls.Link"
mc:Ignorable="d"
d:DesignHeight="150"
d:DesignWidth="300">
<windows:CategoryPanelBase.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.FlatButton.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/light.cobalt.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</windows:CategoryPanelBase.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<DataGrid Name="TimeZoneDataGrid"
SelectionMode="Extended"
Grid.Column="0"
Grid.Row="0"
AutoGenerateColumns="False"
GridLinesVisibility="None"
CanUserResizeRows="False"
IsReadOnly="True"
SelectionUnit="FullRow"
HeadersVisibility="Column"
BorderThickness="1,1,1,1"
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}"
Background="{x:Null}"
SelectionChanged="HandleTimeZoneDataGridSelectionChanged"
d:DataContext="{d:DesignInstance worldClockStatusWindow:TimeZoneEntry }">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Label}"
Header="{x:Static properties:Resources.LabelColumnHeader}"
SortDirection="Ascending"
Width="*" />
<DataGridTextColumn Binding="{Binding TimeZoneId}"
Header="{x:Static properties:Resources.TimeZoneColumnHeader}"
Width="*" />
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow"
BasedOn="{StaticResource MahApps.Styles.DataGridRow}">
<EventSetter Event="MouseDoubleClick"
Handler="HandleTimeZoneDataGridRowMouseDoubleClick" />
</Style>
</DataGrid.RowStyle>
</DataGrid>
<Border Grid.Column="0"
Grid.Row="1"
BorderThickness="1,0,1,1"
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
<StackPanel Orientation="Horizontal"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
<controls:Link Name="AddTimeZoneButton"
Margin="2"
Click="HandleAddTimeZoneButtonClick"
Text="{x:Static properties:Resources.AddTimeZoneLink}"
ToolTip="{x:Static properties:Resources.AddTimeZoneToolTip}">
</controls:Link>
<controls:Link Name="EditTimeZoneButton"
Margin="2"
Click="HandleEditTimeZoneButtonClick"
Text="{x:Static properties:Resources.EditTimeZoneLink}"
ToolTip="{x:Static properties:Resources.EditTimeZoneToolTip}">
</controls:Link>
<controls:Link Name="DeleteTimeZoneButton"
Margin="2"
Click="HandleDeleteTimeZoneButtonClick"
Text="{x:Static properties:Resources.DeleteTimeZoneLink}"
ToolTip="{x:Static properties:Resources.DeleteTimeZoneToolTip}">
</controls:Link>
</StackPanel>
</Border>
</Grid>
</windows:CategoryPanelBase>

View File

@@ -0,0 +1,115 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
namespace WorldClockStatusWindow.SettingsWindow;
public partial class TimeZonesSettingsPanel
{
private CollectionViewSource _collectionViewSource;
public TimeZonesSettingsPanel()
{
InitializeComponent();
}
public override string CategoryName => Properties.Resources.optionCategoryTimeZones;
public override void LoadPanel(Window parentWindow)
{
base.LoadPanel(parentWindow);
if (_collectionViewSource == null)
{
_collectionViewSource = new CollectionViewSource { Source = Data.TimeZoneEntries };
_collectionViewSource.SortDescriptions.Add(new SortDescription("Label", ListSortDirection.Ascending));
TimeZoneDataGrid.ItemsSource = _collectionViewSource.View;
}
_collectionViewSource.View.Refresh();
if (TimeZoneDataGrid.Items.Count > 0)
TimeZoneDataGrid.SelectedIndex = 0;
SetTimeZoneButtonStates();
}
private void HandleTimeZoneDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetTimeZoneButtonStates();
}
private void SetTimeZoneButtonStates()
{
AddTimeZoneButton.IsEnabled = true;
EditTimeZoneButton.IsEnabled = TimeZoneDataGrid.SelectedItems.Count == 1;
DeleteTimeZoneButton.IsEnabled = TimeZoneDataGrid.SelectedItems.Count > 0;
}
private void HandleAddTimeZoneButtonClick(object sender, RoutedEventArgs e)
{
AddTimeZone();
}
private void HandleEditTimeZoneButtonClick(object sender, RoutedEventArgs e)
{
EditSelectedTimeZone();
}
private void HandleDeleteTimeZoneButtonClick(object sender, RoutedEventArgs e)
{
DeleteSelectedTimeZones();
}
private void HandleTimeZoneDataGridRowMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
EditSelectedTimeZone();
}
private void AddTimeZone()
{
var timeZoneEntry = new TimeZoneEntry { TimeZoneId = TimeZoneInfo.Local.Id };
var timeZoneWindow = new TimeZoneWindow();
var result = timeZoneWindow.Display(timeZoneEntry, Window.GetWindow(this));
if (!result.HasValue || !result.Value)
return;
TimeZoneDataGrid.SelectedItem = timeZoneEntry;
SetTimeZoneButtonStates();
}
private void EditSelectedTimeZone()
{
if (TimeZoneDataGrid.SelectedItem == null)
return;
var timeZoneEntry = (TimeZoneEntry) TimeZoneDataGrid.SelectedItem;
var timeZoneWindow = new TimeZoneWindow();
timeZoneWindow.Display(timeZoneEntry, Window.GetWindow(this));
}
private void DeleteSelectedTimeZones()
{
if (MessageBox.Show(ParentWindow!, Properties.Resources.ConfirmDeleteTimeZones, Properties.Resources.ConfirmDeleteTitle, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No)
return;
var selectedItems = new TimeZoneEntry[TimeZoneDataGrid.SelectedItems.Count];
TimeZoneDataGrid.SelectedItems.CopyTo(selectedItems, 0);
foreach (var timeZoneEntry in selectedItems)
Data.TimeZoneEntries.Remove(timeZoneEntry);
SetTimeZoneButtonStates();
}
}