优化更新代码,添加界面功能并整合
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
|
||||
|
||||
|
||||
/* Based on Windows UI Library */
|
||||
|
||||
using WPFluent.Abstractions;
|
||||
using WPFluent.Animations;
|
||||
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace WPFluent.Controls;
|
||||
|
||||
public class NavigationViewContentPresenter : Frame
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="IsDynamicScrollViewerEnabled"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsDynamicScrollViewerEnabledProperty =
|
||||
DependencyProperty.Register(
|
||||
nameof(IsDynamicScrollViewerEnabled),
|
||||
typeof(bool),
|
||||
typeof(NavigationViewContentPresenter),
|
||||
new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="TransitionDuration"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty TransitionDurationProperty = DependencyProperty.Register(
|
||||
nameof(TransitionDuration),
|
||||
typeof(int),
|
||||
typeof(NavigationViewContentPresenter),
|
||||
new FrameworkPropertyMetadata(200));
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the <see cref="Transition"/> dependency property.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty TransitionProperty = DependencyProperty.Register(
|
||||
nameof(Transition),
|
||||
typeof(Transition),
|
||||
typeof(NavigationViewContentPresenter),
|
||||
new FrameworkPropertyMetadata(Transition.FadeInWithSlide));
|
||||
|
||||
static NavigationViewContentPresenter()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata(
|
||||
typeof(NavigationViewContentPresenter),
|
||||
new FrameworkPropertyMetadata(typeof(NavigationViewContentPresenter)));
|
||||
|
||||
NavigationUIVisibilityProperty.OverrideMetadata(
|
||||
typeof(NavigationViewContentPresenter),
|
||||
new FrameworkPropertyMetadata(NavigationUIVisibility.Hidden));
|
||||
|
||||
SandboxExternalContentProperty.OverrideMetadata(
|
||||
typeof(NavigationViewContentPresenter),
|
||||
new FrameworkPropertyMetadata(true));
|
||||
|
||||
JournalOwnershipProperty.OverrideMetadata(
|
||||
typeof(NavigationViewContentPresenter),
|
||||
new FrameworkPropertyMetadata(JournalOwnership.UsesParentJournal));
|
||||
|
||||
ScrollViewer.CanContentScrollProperty.OverrideMetadata(typeof(Page), new FrameworkPropertyMetadata(true));
|
||||
}
|
||||
|
||||
public NavigationViewContentPresenter()
|
||||
{
|
||||
Navigating += static(sender, eventArgs) =>
|
||||
{
|
||||
if(eventArgs.Content is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var self = (NavigationViewContentPresenter)sender;
|
||||
self.OnNavigating(eventArgs);
|
||||
};
|
||||
|
||||
Navigated += static(sender, eventArgs) =>
|
||||
{
|
||||
var self = (NavigationViewContentPresenter)sender;
|
||||
|
||||
if(eventArgs.Content is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.OnNavigated(eventArgs);
|
||||
};
|
||||
}
|
||||
|
||||
private void ApplyTransitionEffectToNavigatedPage(object content)
|
||||
{
|
||||
if(TransitionDuration < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ = TransitionAnimationProvider.ApplyTransition(content, Transition, TransitionDuration);
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage(
|
||||
"ReSharper",
|
||||
"SuspiciousTypeConversion.Global",
|
||||
Justification = "The library user might make a class inherit from both FrameworkElement and INavigationAware at the same time.")]
|
||||
private static void NotifyContentAboutNavigating(object content, Func<INavigationAware, Task> function)
|
||||
{
|
||||
// The order in which the OnNavigatedToAsync/OnNavigatedFromAsync methods of View and ViewModel are called
|
||||
// is not guaranteed
|
||||
if(content is INavigationAware navigationAwareContent)
|
||||
{
|
||||
function(navigationAwareContent);
|
||||
}
|
||||
|
||||
if(content is INavigableView<object> { ViewModel: INavigationAware navigationAwareViewModel })
|
||||
{
|
||||
function(navigationAwareViewModel);
|
||||
}
|
||||
else if(content is FrameworkElement { DataContext: INavigationAware viewModel } &&
|
||||
!ReferenceEquals(viewModel, content))
|
||||
{
|
||||
function(viewModel);
|
||||
}
|
||||
}
|
||||
|
||||
private static void NotifyContentAboutNavigatingFrom(object content)
|
||||
{ NotifyContentAboutNavigating(content, navigationAware => navigationAware.OnNavigatedFromAsync()); }
|
||||
|
||||
private static void NotifyContentAboutNavigatingTo(object content)
|
||||
{ NotifyContentAboutNavigating(content, navigationAware => navigationAware.OnNavigatedToAsync()); }
|
||||
|
||||
protected override void OnInitialized(EventArgs e)
|
||||
{
|
||||
base.OnInitialized(e);
|
||||
|
||||
// REVIEW: I didn't understand something, but why is it necessary?
|
||||
Unloaded += static(sender, _) =>
|
||||
{
|
||||
if(sender is NavigationViewContentPresenter navigator)
|
||||
{
|
||||
NotifyContentAboutNavigatingFrom(navigator.Content);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
||||
{
|
||||
if(e.ChangedButton is MouseButton.XButton1 or MouseButton.XButton2)
|
||||
{
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected virtual void OnNavigated(NavigationEventArgs eventArgs)
|
||||
{
|
||||
ApplyTransitionEffectToNavigatedPage(eventArgs.Content);
|
||||
|
||||
if(eventArgs.Content is not DependencyObject dependencyObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetCurrentValue(IsDynamicScrollViewerEnabledProperty, ScrollViewer.GetCanContentScroll(dependencyObject));
|
||||
}
|
||||
|
||||
protected virtual void OnNavigating(System.Windows.Navigation.NavigatingCancelEventArgs eventArgs)
|
||||
{
|
||||
NotifyContentAboutNavigatingTo(eventArgs.Content);
|
||||
|
||||
if(eventArgs.Navigator is not NavigationViewContentPresenter navigator)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NotifyContentAboutNavigatingFrom(navigator.Content);
|
||||
}
|
||||
|
||||
protected override void OnPreviewKeyDown(KeyEventArgs e)
|
||||
{
|
||||
if(e.Key == Key.F5)
|
||||
{
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnPreviewKeyDown(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the dynamic scroll viewer is enabled.
|
||||
/// </summary>
|
||||
public bool IsDynamicScrollViewerEnabled
|
||||
{
|
||||
get => (bool)GetValue(IsDynamicScrollViewerEnabledProperty);
|
||||
protected set => SetValue(IsDynamicScrollViewerEnabledProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets type of <see cref="NavigationViewContentPresenter"/> transitions during navigation.
|
||||
/// </summary>
|
||||
public Transition Transition
|
||||
{
|
||||
get => (Transition)GetValue(TransitionProperty);
|
||||
set => SetValue(TransitionProperty, value);
|
||||
}
|
||||
|
||||
[Bindable(true)]
|
||||
[Category("Appearance")]
|
||||
public int TransitionDuration
|
||||
{
|
||||
get => (int)GetValue(TransitionDurationProperty);
|
||||
set => SetValue(TransitionDurationProperty, value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user