Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
</ResourceDictionary>

</ControlTemplate.Resources>
<ui:ElevationBorder x:Name="PART_RootBorder"
<Border x:Name="PART_RootBorder"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
MaxWidth="{TemplateBinding MaxWidth}"
Expand All @@ -88,7 +88,8 @@
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding ui:ControlHelper.CornerRadius}">
CornerRadius="{TemplateBinding ui:ControlHelper.CornerRadius}"
ui:FocusVisualHelper.IsTemplateFocusTarget="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<ui:VisualStateGroupListener.Listener>
Expand Down Expand Up @@ -382,7 +383,7 @@
ToolTipService.ToolTip="{TemplateBinding ActionIconToolTip}" />
</Viewbox>
</Grid>
</ui:ElevationBorder>
</Border>


<ControlTemplate.Triggers>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding chelper:ControlHelper.CornerRadius}"
SnapsToDevicePixels="True">
SnapsToDevicePixels="True"
ui:FocusVisualHelper.IsTemplateFocusTarget="True">
<Border
x:Name="Border"
Padding="{TemplateBinding Padding}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
-->
<ContentControl
x:Name="ContentControl"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Expand Down Expand Up @@ -76,14 +77,15 @@
IsChecked="{Binding Path=IsOverflowOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
IsEnabled="{TemplateBinding HasOverflowItems}"
Style="{DynamicResource EllipsisButton}"
ui:FocusVisualHelper.IsTemplateFocusTarget="True"
Visibility="{TemplateBinding EffectiveOverflowButtonVisibility}">
<ui:FontIcon
x:Name="EllipsisIcon"
Height="{DynamicResource AppBarExpandButtonCircleDiameter}"
VerticalAlignment="Center"
FontFamily="{DynamicResource FluentSystemIcons}"
FontFamily="{DynamicResource SymbolThemeFontFamily}"
FontSize="20"
Glyph="&#xE826;" />
Glyph="&#xE712;" />
</ToggleButton>
<Rectangle
x:Name="HighContrastBorder"
Expand Down Expand Up @@ -129,6 +131,7 @@
</primitives:CommandBarOverflowPresenter.Resources>
<primitives:CommandBarOverflowPanel
x:Name="PART_ToolBarOverflowPanel"
Margin="{DynamicResource CommandBarOverflowPresenterMargin}"
FocusVisualStyle="{x:Null}"
Focusable="true"
KeyboardNavigation.DirectionalNavigation="Cycle"
Expand Down Expand Up @@ -210,7 +213,6 @@
SnapsToDevicePixels="True">
<Border Padding="{TemplateBinding Padding}" CornerRadius="{TemplateBinding CornerRadius}">
<ui:ScrollViewerEx
Padding="{DynamicResource CommandBarOverflowPresenterMargin}"
Content="{TemplateBinding Content}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding ui:ControlHelper.CornerRadius}"
ui:FocusVisualHelper.IsTemplateFocusTarget="True"
SnapsToDevicePixels="True">
<Border
x:Name="Border"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<Setter Property="BorderThickness" Value="{DynamicResource MenuFlyoutItemRevealBorderThickness}" />
<Setter Property="Foreground" Value="{DynamicResource MenuFlyoutItemForeground}" />
<Setter Property="Padding" Value="{DynamicResource MenuFlyoutItemThemePadding}" />
<Setter Property="ui:ControlHelper.CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="UseSystemFocusVisuals" Value="{DynamicResource UseSystemFocusVisuals}" />
<Setter Property="ui:FocusVisualHelper.FocusVisualMargin" Value="0,0,0,5" />
<Setter Property="ui:ControlHelper.CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="MaxHeight" Value="{DynamicResource LoopingSelectorMaxHeight}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
Expand All @@ -99,7 +99,7 @@
Focusable="false"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Hidden">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="0,-3,0,0"/>
</ScrollViewer>
<RepeatButton
x:Name="UpButton"
Expand Down Expand Up @@ -394,7 +394,7 @@
Grid.ColumnSpan="7"
Height="{DynamicResource TimePickerFlyoutPresenterHighlightHeight}"
IsHitTestVisible="False"
Margin="4,6,4,0"
Margin="4,2,4,2"
VerticalAlignment="Center"
BorderThickness="0"
CornerRadius="{TemplateBinding CornerRadius}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<Setter Property="MinWidth" Value="{DynamicResource ToggleSwitchThemeMinWidth}" />
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
<Setter Property="ui:FocusVisualHelper.FocusVisualMargin" Value="-7,-3,-7,-3" />
<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ToggleSwitch">
Expand Down Expand Up @@ -123,6 +124,8 @@
Visibility="Collapsed" />
<Grid
Grid.Row="1"
ui:FocusVisualHelper.IsTemplateFocusTarget="True"
ui:ControlHelper.CornerRadius="{TemplateBinding CornerRadius}"
HorizontalAlignment="Left"
VerticalAlignment="Top">

Expand All @@ -144,7 +147,6 @@
Grid.RowSpan="3"
Grid.ColumnSpan="5"
Margin="0,5"
ui:FocusVisualHelper.IsTemplateFocusTarget="True"
Background="{DynamicResource ToggleSwitchContainerBackground}"
CornerRadius="{TemplateBinding CornerRadius}" />
<ui:ContentPresenterEx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<sys:Double x:Key="ExampleMaxWidth">1000</sys:Double>

<Style TargetType="local:ControlExample">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ControlExample">
Expand All @@ -37,7 +38,6 @@
<Run>
This sample requires a later version of Windows to be fully functional. Learn more about version adaptive apps:
</Run>
<Hyperlink NavigateUri="https://docs.microsoft.com/windows/uwp/debug-test-perf/version-adaptive-apps">https://docs.microsoft.com/windows/uwp/debug-test-perf/version-adaptive-apps</Hyperlink>
</TextBlock>

<Border Grid.Row="2" CornerRadius="8">
Expand Down
212 changes: 211 additions & 1 deletion source/iNKORE.UI.WPF.Modern/Controls/Helpers/CalendarHelper.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using System.Windows;
using System;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using Calendar = System.Windows.Controls.Calendar;

namespace iNKORE.UI.WPF.Modern.Controls.Helpers
{
Expand Down Expand Up @@ -52,5 +57,210 @@ private static void OnCalendarGotMouseCapture(object sender, MouseEventArgs e)
}
}
}

#region CalendarKeyboardBehaviorOverride

public static bool GetKeyboardBehaviorOverride(Calendar calendar) =>
(bool)calendar.GetValue(KeyboardBehaviorOverrideProperty);

public static void SetKeyboardBehaviorOverride(Calendar calendar, bool value) =>
calendar.SetValue(KeyboardBehaviorOverrideProperty, value);

public static readonly DependencyProperty KeyboardBehaviorOverrideProperty =
DependencyProperty.RegisterAttached(
"KeyboardBehaviorOverride",
typeof(bool),
typeof(CalendarHelper),
new PropertyMetadata(OnKeyboardBehaviorOverrideChanged));

private static void OnKeyboardBehaviorOverrideChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not Calendar calendar)
{
return;
}

if (e.NewValue is true)
{
calendar.PreviewKeyDown += OnHandleChangeFocusByKeys;
}
else
{
calendar.PreviewKeyDown -= OnHandleChangeFocusByKeys;
}
}

private static void OnHandleChangeFocusByKeys(object sender, KeyEventArgs e)
{
if (sender is not Calendar calendar ||
(Keyboard.Modifiers & ModifierKeys.Control) is ModifierKeys.Control)
{
return;
}

if ((Keyboard.Modifiers & ModifierKeys.Shift) is ModifierKeys.Shift && e.Key is not Key.Tab)
{
e.Handled = true;
return;
}

DateTime? focusTarget;
switch (calendar.DisplayMode)
{
case CalendarMode.Month:
int? change = e.Key switch
{
Key.Up => -7,
Key.Down => 7,
Key.Left => -1,
Key.Right => 1,
_ => null
};

if (change is null)
{
return;
}

var currentDate = typeof(Calendar).GetProperty("CurrentDate",
BindingFlags.NonPublic | BindingFlags.Instance)!
.GetValue(calendar)
as DateTime?;

focusTarget = GetNonBlackoutTarget(calendar, currentDate?.AddDays(change.Value));

break;

case CalendarMode.Year:
if (GetChangeForYearOrDecadeView(e.Key) is not { } monthChange)
{
return;
}

focusTarget = calendar.DisplayDate.AddMonths(monthChange);
break;
case CalendarMode.Decade:
if (GetChangeForYearOrDecadeView(e.Key) is not { } yearChange)
{
return;
}

focusTarget = calendar.DisplayDate.AddYears(yearChange);
break;
default:
return;
}

typeof(Calendar).GetMethod("MoveDisplayTo", BindingFlags.NonPublic | BindingFlags.Instance)!
.Invoke(calendar,
[focusTarget]);

e.Handled = true;

static int? GetChangeForYearOrDecadeView(Key key) => key switch
{
Key.Up => -4,
Key.Down => 4,
Key.Left => -1,
Key.Right => 1,
_ => null
};

static DateTime? GetNonBlackoutTarget(Calendar calendar, DateTime? targetFocus)
{
var blackoutDates =
typeof(Calendar).GetField("_blackoutDates", BindingFlags.NonPublic | BindingFlags.Instance)!
.GetValue(calendar)
as CalendarBlackoutDatesCollection;

var toSelectDate =
typeof(CalendarBlackoutDatesCollection).GetMethod("GetNonBlackoutDate",
BindingFlags.NonPublic | BindingFlags.Instance)!
.Invoke(blackoutDates, [targetFocus, -1]) as DateTime?;
return toSelectDate;
}
}

private static DateTime? GetCurrentFocusedDate() =>
(Keyboard.FocusedElement as FrameworkElement)?.DataContext as DateTime?;

#endregion

#region ContainsToday

public static CalendarMode? GetCalendarDisplayMode(DependencyObject obj) => (CalendarMode?)obj.GetValue(CalendarDisplayModeProperty);

public static void SetCalendarDisplayMode(DependencyObject obj, CalendarMode? value) => obj.SetValue(CalendarDisplayModeProperty, value);

public static readonly DependencyProperty CalendarDisplayModeProperty =
DependencyProperty.RegisterAttached(
"CalendarDisplayMode",
typeof(CalendarMode?),
typeof(CalendarHelper),
new PropertyMetadata(null, OnContainsTodayNeedsUpdate));

public static object GetContextDate(DependencyObject obj) => obj.GetValue(ContextDateProperty);

public static void SetContextDate(DependencyObject obj, object value) => obj.SetValue(ContextDateProperty, value);

public static readonly DependencyProperty ContextDateProperty =
DependencyProperty.RegisterAttached(
"ContextDate",
typeof(object),
typeof(CalendarHelper),
new PropertyMetadata(null, OnContainsTodayNeedsUpdate));

public static bool GetIsContainsTodayActive(DependencyObject obj) => (bool)obj.GetValue(IsContainsTodayActiveProperty);

public static void SetIsContainsTodayActive(DependencyObject obj, bool value) => obj.SetValue(IsContainsTodayActiveProperty, value);

public static readonly DependencyProperty IsContainsTodayActiveProperty =
DependencyProperty.RegisterAttached(
"IsContainsTodayActive",
typeof(bool),
typeof(CalendarHelper),
new PropertyMetadata(true, OnContainsTodayNeedsUpdate));

private static void OnContainsTodayNeedsUpdate(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UpdateContainsTodayActive(d);
}

private static void UpdateContainsTodayActive(DependencyObject d)
{
var mode = GetCalendarDisplayMode(d);
var contextDate = GetContextDate(d) as DateTime?;

if (!mode.HasValue || !contextDate.HasValue)
{
SetContainsToday(d, false);
return;
}

var containsTodayActive = mode.Value switch
{
CalendarMode.Year => contextDate.Value.Year == DateTime.Today.Year &&
contextDate.Value.Month == DateTime.Today.Month,
CalendarMode.Decade => contextDate.Value.Year == DateTime.Today.Year,
_ => false
};

SetContainsToday(d, containsTodayActive);
}

public static bool GetContainsToday(DependencyObject obj) =>
(bool)obj.GetValue(ContainsTodayProperty);

public static void SetContainsToday(DependencyObject obj, bool value) =>
obj.SetValue(ContainsTodayProperty, value);

public static readonly DependencyProperty ContainsTodayProperty =
DependencyProperty.RegisterAttached(
"ContainsToday",
typeof(bool),
typeof(CalendarHelper),
new PropertyMetadata(false));

#endregion
}
}
Loading
Loading