Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows 10X and Two-pane view support #3768

Closed
wants to merge 2 commits into from
Closed
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 @@ -2,12 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.ComponentModel;

using Microsoft.Toolkit.Uwp.UI.Controls.Design.Properties;

using Microsoft.VisualStudio.DesignTools.Extensibility;
using Microsoft.VisualStudio.DesignTools.Extensibility.Metadata;
using System.ComponentModel;

namespace Microsoft.Toolkit.Uwp.UI.Controls.Design
{
Expand All @@ -25,6 +23,7 @@ public ListDetailsViewMetadata()
new EditorBrowsableAttribute(EditorBrowsableState.Advanced)
);
b.AddCustomAttributes(nameof(ListDetailsView.ListPaneBackground), new CategoryAttribute(Resources.CategoryBrush));
b.AddCustomAttributes(nameof(ListDetailsView.DetailsPaneBackground), new CategoryAttribute(Resources.CategoryBrush));
b.AddCustomAttributes(nameof(ListDetailsView.ListHeader), new CategoryAttribute(Resources.CategoryCommon));
b.AddCustomAttributes(nameof(ListDetailsView.ListHeaderTemplate),
new CategoryAttribute(Resources.CategoryAppearance),
Expand All @@ -36,6 +35,11 @@ public ListDetailsViewMetadata()
new CategoryAttribute(Resources.CategoryCommon),
new EditorBrowsableAttribute(EditorBrowsableState.Advanced)
);
AddCustomAttributes(nameof(ListDetailsView.ListPaneNoItemsContent), new CategoryAttribute(Resources.CategoryCommon));
b.AddCustomAttributes(nameof(ListDetailsView.ListPaneNoItemsContentTemplate),
new CategoryAttribute(Resources.CategoryCommon),
new EditorBrowsableAttribute(EditorBrowsableState.Advanced)
);
b.AddCustomAttributes(nameof(ListDetailsView.ViewState), new CategoryAttribute(Resources.CategoryCommon));
b.AddCustomAttributes(nameof(ListDetailsView.ListCommandBar), new CategoryAttribute(Resources.CategoryCommon));
b.AddCustomAttributes(nameof(ListDetailsView.DetailsCommandBar), new CategoryAttribute(Resources.CategoryCommon));
Expand All @@ -44,4 +48,4 @@ public ListDetailsViewMetadata()
);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;

namespace Microsoft.Toolkit.Uwp.UI.Controls.Design
{
internal static partial class ControlTypes
Expand All @@ -15,6 +13,11 @@ internal static class ListDetailsView
{
internal const string DetailsCommandBar = nameof(DetailsCommandBar);
internal const string DetailsTemplate = nameof(DetailsTemplate);
internal const string DetailsPaneBackground = nameof(DetailsPaneBackground);
internal const string DetailsContentTemplateSelector = nameof(DetailsContentTemplateSelector);
internal const string ListPaneItemTemplateSelector = nameof(ListPaneItemTemplateSelector);
internal const string ListPaneNoItemsContentTemplate = nameof(ListPaneNoItemsContentTemplate);
internal const string ListPaneNoItemsContent = nameof(ListPaneNoItemsContent);
internal const string ListCommandBar = nameof(ListCommandBar);
internal const string ListHeader = nameof(ListHeader);
internal const string ListHeaderTemplate = nameof(ListHeaderTemplate);
Expand All @@ -25,4 +28,4 @@ internal static class ListDetailsView
internal const string SelectedItem = nameof(SelectedItem);
internal const string ViewState = nameof(ViewState);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public enum BackButtonBehavior
/// </summary>
/// <remarks>
/// If the back button controlled by <see cref="Windows.UI.Core.SystemNavigationManager"/> is already visible, the <see cref="ListDetailsView"/> will hook into that button.
/// If the new NavigationView provided by the Windows UI nuget package is used, the <see cref="ListDetailsView"/> will enable and show that button.
/// If the new NavigationView provided by the Windows UI NuGet package is used, the <see cref="ListDetailsView"/> will enable and show that button.
/// Otherwise the inline button is used.
/// </remarks>
Automatic,
Expand All @@ -34,4 +34,4 @@ public enum BackButtonBehavior
/// </summary>
Manual,
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Reflection;
using Windows.ApplicationModel;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Microsoft.Toolkit.Uwp.UI.Controls
{
/// <summary>
/// Panel that allows for a List/Details pattern.
/// </summary>
/// <seealso cref="ItemsControl" />
public partial class ListDetailsView
{
private AppViewBackButtonVisibility? _previousSystemBackButtonVisibility;
private bool _previousNavigationViewBackEnabled;

// Int used because the underlying type is an enum, but we don't have access to the enum
private int _previousNavigationViewBackVisibilty;
private Button _inlineBackButton;
private object _navigationView;
private Frame _frame;

/// <summary>
/// Sets the back button visibility based on the current visual state and selected item
/// </summary>
private void SetBackButtonVisibility(ListDetailsViewState? previousState = null)
{
const int backButtonVisible = 1;

if (DesignMode.DesignModeEnabled)
{
return;
}

if (ViewState == ListDetailsViewState.Details)
{
if ((BackButtonBehavior == BackButtonBehavior.Inline) && (_inlineBackButton != null))
{
_inlineBackButton.Visibility = Visibility.Visible;
}
else if (BackButtonBehavior == BackButtonBehavior.Automatic)
{
// Continue to support the system back button if it is being used
SystemNavigationManager navigationManager = SystemNavigationManager.GetForCurrentView();
if (navigationManager.AppViewBackButtonVisibility == AppViewBackButtonVisibility.Visible)
{
// Setting this indicates that the system back button is being used
_previousSystemBackButtonVisibility = navigationManager.AppViewBackButtonVisibility;
}
else if ((_inlineBackButton != null) && ((_navigationView == null) || (_frame == null)))
{
// We can only use the new NavigationView if we also have a Frame
// If there is no frame we have to use the inline button
_inlineBackButton.Visibility = Visibility.Visible;
}
else
{
SetNavigationViewBackButtonState(backButtonVisible, true);
}
}
else if (BackButtonBehavior != BackButtonBehavior.Manual)
{
SystemNavigationManager navigationManager = SystemNavigationManager.GetForCurrentView();
_previousSystemBackButtonVisibility = navigationManager.AppViewBackButtonVisibility;

navigationManager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
}
}
else if (previousState == ListDetailsViewState.Details)
{
if ((BackButtonBehavior == BackButtonBehavior.Inline) && (_inlineBackButton != null))
{
_inlineBackButton.Visibility = Visibility.Collapsed;
}
else if (BackButtonBehavior == BackButtonBehavior.Automatic)
{
if (!_previousSystemBackButtonVisibility.HasValue)
{
if ((_inlineBackButton != null) && ((_navigationView == null) || (_frame == null)))
{
_inlineBackButton.Visibility = Visibility.Collapsed;
}
else
{
SetNavigationViewBackButtonState(_previousNavigationViewBackVisibilty, _previousNavigationViewBackEnabled);
}
}
}

if (_previousSystemBackButtonVisibility.HasValue)
{
// Make sure we show the back button if the stack can navigate back
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = _previousSystemBackButtonVisibility.Value;
_previousSystemBackButtonVisibility = null;
}
}
}

private void SetNavigationViewBackButtonState(int visible, bool enabled)
{
if (_navigationView == null)
{
return;
}

System.Type navType = _navigationView.GetType();
PropertyInfo visibleProperty = navType.GetProperty("IsBackButtonVisible");
if (visibleProperty != null)
{
_previousNavigationViewBackVisibilty = (int)visibleProperty.GetValue(_navigationView);
visibleProperty.SetValue(_navigationView, visible);
}

PropertyInfo enabledProperty = navType.GetProperty("IsBackEnabled");
if (enabledProperty != null)
{
_previousNavigationViewBackEnabled = (bool)enabledProperty.GetValue(_navigationView);
enabledProperty.SetValue(_navigationView, enabled);
}
}

/// <summary>
/// Closes the details pane if we are in narrow state
/// </summary>
/// <param name="sender">The sender</param>
/// <param name="args">The event args</param>
private void OnFrameNavigating(object sender, NavigatingCancelEventArgs args)
{
if ((args.NavigationMode == NavigationMode.Back) && (ViewState == ListDetailsViewState.Details))
{
ClearSelectedItem();
args.Cancel = true;
}
}

/// <summary>
/// Closes the details pane if we are in narrow state
/// </summary>
/// <param name="sender">The sender</param>
/// <param name="args">The event args</param>
private void OnBackRequested(object sender, BackRequestedEventArgs args)
{
if (ViewState == ListDetailsViewState.Details)
{
// let the OnFrameNavigating method handle it if
if (_frame == null || !_frame.CanGoBack)
{
ClearSelectedItem();
}

args.Handled = true;
}
}

private void OnInlineBackButtonClicked(object sender, RoutedEventArgs e)
{
ClearSelectedItem();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
/// <summary>
/// Panel that allows for a List/Details pattern.
/// </summary>
/// <seealso cref="Windows.UI.Xaml.Controls.ItemsControl" />
/// <seealso cref="ItemsControl" />
public partial class ListDetailsView
{
/// <summary>
Expand All @@ -19,7 +19,7 @@ public partial class ListDetailsView
public event SelectionChangedEventHandler SelectionChanged;

/// <summary>
/// Occurs when the view state changes
/// Occurs when the view state changes.
/// </summary>
public event EventHandler<ListDetailsViewState> ViewStateChanged;

Expand All @@ -28,4 +28,4 @@ private void OnSelectionChanged(SelectionChangedEventArgs e)
SelectionChanged?.Invoke(this, e);
}
}
}
}
Loading