Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/usausa/smart-net-navigation
Navigation library for WPF/MAUI/Windows Forms.
https://github.com/usausa/smart-net-navigation
csharp dotnet dotnet-core dotnetcore maui navigation smart windows-forms wpf xamarin
Last synced: 23 days ago
JSON representation
Navigation library for WPF/MAUI/Windows Forms.
- Host: GitHub
- URL: https://github.com/usausa/smart-net-navigation
- Owner: usausa
- License: mit
- Created: 2016-02-24T04:41:29.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2024-04-17T01:20:09.000Z (7 months ago)
- Last Synced: 2024-05-16T11:25:57.163Z (6 months ago)
- Topics: csharp, dotnet, dotnet-core, dotnetcore, maui, navigation, smart, windows-forms, wpf, xamarin
- Language: C#
- Homepage:
- Size: 2.49 MB
- Stars: 19
- Watchers: 5
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Smart.Navigation .NET - navigation library for .NET
[![NuGet Badge](https://buildstats.info/nuget/Usa.Smart.Navigation)](https://www.nuget.org/packages/Usa.Smart.Navigation/)
## What is this ?
* Navigation by control switching.
* Navigationg to view by id.
* Multiplatform support.
* MVVM support with WPF and Xamarin.Forms provider.
* Parameter support between target.
* Stacked navigation support.
* Lifecycle event support.
* Cancel event support.
* Plugin support.
* Library integration support.### Usage example
```csharp
// Config Navigator
navigator = new NavigatorConfig()
.UseFormsNavigationProvider()
.UseResolver(resolver)
.UseIdViewMapper(m => m.AutoRegister(Assembly.GetExecutingAssembly().ExportedTypes))
.ToNavigator();// Navigate to view
navigator.Forward(ViewId.Menu);
```## NuGet
| Package | Note |
|-|-|
| [![NuGet Badge](https://buildstats.info/nuget/Usa.Smart.Navigation)](https://www.nuget.org/packages/Usa.Smart.Navigation/) | Core libyrary |
| [![NuGet Badge](https://buildstats.info/nuget/Usa.Smart.Navigation.Resolver)](https://www.nuget.org/packages/Usa.Smart.Navigation.Resolver/) | Smart.Resolver integration |
| [![NuGet Badge](https://buildstats.info/nuget/Usa.Smart.Navigation.Forms)](https://www.nuget.org/packages/Usa.Smart.Navigation.Forms/) | Xamarin.Forms provider |
| [![NuGet Badge](https://buildstats.info/nuget/Usa.Smart.Navigation.Windows)](https://www.nuget.org/packages/Usa.Smart.Navigation.Windows/) | WPF provider |
| [![NuGet Badge](https://buildstats.info/nuget/Usa.Smart.Navigation.Windows.Forms)](https://www.nuget.org/packages/Usa.Smart.Navigation.Windows.Forms/) | Windows Forms provider |## Supported platform
### Windows Forms
``Control`` is a container and ``Control`` is a view.
```csharp
navigator = new NavigatorConfig()
.UseControlNavigationProvider(ContainerPanel)
.ToNavigator();
```### WPF
``ContentControl`` is a container and ``Control`` is a view.
```csharp
navigator = new NavigatorConfig()
.UseWindowsNavigationProvider()
.ToNavigator();
``````xml
```
### Xamarin.Forms
``ContentView`` is a container and ``View`` is a view.
```csharp
navigator = new NavigatorConfig()
.UseFormsNavigationProvider()
.ToNavigator();
``````xml
```
### Create custom platform support
Implement the following interface.
```csharp
public interface INavigationProvider
{
// Resolve target(DataContext/BindingContext) from view
object ResolveTarget(object view);// Add view to container
void OpenView(object view);// Remove view from container and dispose
void CloseView(object view);// Restore view from stack
void ActiveView(object view, object parameter);// Deactive view
object DeactiveView(object view);
}
```## View mapper
### Id to Type dictionary mapping
```csharp
// Configuration method
NavigatorConfig UseIdViewMapper(Action action);// Register interface
public interface IIdViewRegister
{
void Register(object id, Type type);
}// Auto register extension
void AutoRegister(IEnumerable types);
``````csharp
// Usage
public enum ViewId
{
ViewList,
ViewDetailNew,
ViewDetailUpdate
}[View(ViewId.ViewList)]
public sealed class ViewList
{
}[View(ViewId.ViewDetailNew)]
[View(ViewId.ViewDetailUpdate)]
public sealed class ViewDetail
{
}// config
var navigator = new NavigatorConfig()
.UseSomeProvider()
.UseIdViewMapper(m => m.AutoRegister(Assembly.GetExecutingAssembly().ExportedTypes))
.ToNavigator();// navigation
navigator.Forward(ViewId.ViewList);```
### Direct type mapping (default)
```csharp
// Configuration method
NavigatorConfig UseDirectViewMapper();
``````csharp
// config
var navigator = new NavigatorConfig()
.UseSomeProvider()
.UseDirectViewMapper()
.ToNavigator();// navigation
navigator.Forward(typeof(View1));```
### Path mapping
```csharp
// Configuration method
NavigatorConfig UsePathViewMapper(Action action)
``````csharp
// Usage
namespace Example.Views
{
public sealed class ParentView
{
}
}namespace Example.Views.Children
{
public sealed class Child1View
{
}public sealed class Child2View
{
}
}// config
var navigator = new NavigatorConfig()
.UseMockFormProvider()
.UsePathViewMapper(option =>
{
option.Root = "Example.Views";
option.Suffix = "View";
option.AddAssembly(Assembly.GetExecutingAssembly());
})
.ToNavigator();// navigation
navigator.Forward("/Parent");
navigator.Forward("/Children/Child1");
navigator.Forward("Child2");
navigator.Forward("../Parent");
navigator.Forward("Children/Child2");
```## Navigation
### Forward
Non stacked navigation.
```csharp
bool Forward(object id);bool Forward(object id, INavigationParameter parameter);
Task ForwardAsync(object id);
Task ForwardAsync(object id, INavigationParameter parameter);
```### Push
Stacked navigation.
```csharp
bool Push(object id);bool Push(object id, INavigationParameter parameter);
Task PushAsync(object id);
Task PushAsync(object id, INavigationParameter parameter);
```### Pop
Pop stack navigation.
```csharp
bool Pop();bool Pop(INavigationParameter parameter);
bool Pop(int level);
bool Pop(int level, INavigationParameter parameter);
Task PopAsync();
Task PopAsync(INavigationParameter parameter);
Task PopAsync(int level);
Task PopAsync(int level, INavigationParameter parameter);
```### PopAndForward
Pop with Forward navigation.
```csharp
bool PopAndForward(object id);bool PopAndForward(object id, int level);
bool PopAllAndForward(object id);
bool PopAndForward(object id, INavigationParameter parameter);
bool PopAndForward(object id, int level, INavigationParameter parameter);
bool PopAllAndForward(object id, INavigationParameter parameter);
Task PopAndForwardAsync(object id);
Task PopAndForwardAsync(object id, int level);
Task PopAllAndForwardAsync(object id);
Task PopAndForwardAsync(object id, INavigationParameter parameter);
Task PopAndForwardAsync(object id, int level, INavigationParameter parameter);
Task PopAllAndForwardAsync(object id, INavigationParameter parameter);
```### Create custom navigation
Implement the following interface to create custom navigation.
```csharp
public interface INavigationStrategy
{
// Initialize
StragtegyResult Initialize(INavigationController controller);// Resolve next view
object ResolveToView(INavigationController controller);// Stack update
void UpdateStack(INavigationController controller, object toView);
}
```## Navigator property
```csharp
public interface INavigator
{
// Stack count
int StackedCount { get; }// Current view id
object CurrentViewId { get; }// Current view instance
object CurrentView { get; }// Current target(DataContext/BindingContext or view itself) instance
object CurrentTarget { get; }// Navigating status
bool Executing { get; }
}
```## Event
### INavigationEventSupport
```csharp
public interface INavigationEventSupport
{
// From page event berfore stack changed
void OnNavigatingFrom(INavigationContext context);// To page event berfore stack changed
void OnNavigatingTo(INavigationContext context);// To page event after stack changed
void OnNavigatedTo(INavigationContext context);
}
`````INavigationContext`` has navigation information.
```csharp
public interface INavigationContext
{
object FromId { get; }object ToId { get; }
NavigationAttributes Attribute { get; }
INavigationParameter Parameter { get; }
}
`````INavigationParameter`` is navigation parameteter store.
```csharp
public interface INavigationParameter
{
T GetValue(string key);T GetValue();
T GetValueOrDefault(string key);
T GetValueOrDefault();
T GetValueOr(string key, T defaultValue);
T GetValueOr(T defaultValue);
}
`````NavigationAttributes`` has the following extension methods.
```csharp
public static class NavigationAttributesExtensions
{
public static bool IsStacked(this NavigationAttributes attributes);public static bool IsRestore(this NavigationAttributes attributes);
}
```### INavigator events
```csharp
public interface INavigator
{
// Cancel confirm event
event EventHandler Confirm;// Navigating event before stack changed
event EventHandler Navigating;// Navigating event after stack changed
event EventHandler Navigated;// Navigator exit event
event EventHandler Exited;// Navigation executing changed event
event EventHandler ExecutingChanged;
}
`````ConfirmEventArgs`` is ``CancelEventArgs`` with ``INavigationContext``.
```csharp
public sealed class ConfirmEventArgs : CancelEventArgs
{
public INavigationContext Context { get; }
}
`````NavigationEventArgs`` has ``INavigationContext`` and view instance information.
```csharp
public sealed class NavigationEventArgs : EventArgs
{
public INavigationContext Context { get; }public object FromView { get; }
public object FromTarget { get; }
public object ToView { get; }
public object ToTarget { get; }
}
```## Supported interfaces
### IConfirmRequest/IConfirmRequestAsync
Cancel when false is returned.
```csharp
public interface IConfirmRequest
{
bool CanNavigate(INavigationContext context);
}
``````csharp
public interface IConfirmRequestAsync
{
Task CanNavigateAsync(INavigationContext context);
}
```### INotifySupport/INotifySupportAsync
Navigator external notification reception interface.
```csharp
public interface INotifySupport
{
void NavigatorNotify(object parameter);
}public interface INotifySupport
{
void NavigatorNotify(T parameter);
}public interface INotifySupportAsync
{
Task NavigatorNotifyAsync(object parameter);
}public interface INotifySupportAsync
{
Task NavigatorNotifyAsync(T parameter);
}
```Notification method is as follows.
```csharp
// Usage
navigator.Notyfy(parameter);// Usage(Async)
await navigator.NotyfyAsync(parameter);
```### INavigatorAware
Navigator is injected.
```csharp
public interface INavigatorAware
{
INavigator Navigator { get; set; }
}
```## Plugins
### Parameter plugin
Previous parameter is set next.
```csharp
public sealed class View1
{
[Parameter]
public int IntParameter { get; set; }
}public sealed class View2
{
[Parameter]
public int IntParameter { get; set; }
}// Test
navigator.Forward(typeof(View1));var view1 = (View1)navigator.CurrentView;
view1.IntParameter = 123;navigator.Forward(typeof(View2));
var view2 = (View2)navigator.CurrentView;
Assert.Equal(123, view2.IntParameter);
```* Set to property with same name.
* Even if the name of the property is different, it can be specified by attribute.
* I/O direction can be limited by ``Directions.Import``/``Directions.Export``.
* When different types are converted by IConverter.### Scope plugin
Inject object that exist between scopes.
```csharp
public sealed class ScopeData : IInitializable, IDisposable
{
...
}public sealed class Data1View
{
}public sealed class Data2View
{
[Scope]
public ScopeData Data { get; set; }
}public sealed class Data3View
{
[Scope]
public ScopeData Data { get; set; }
}// Test
navigator.Forward(typeof(Data1View));navigator.Forward(typeof(Data2View)); // ScopeDate create and initialized
var view2 = (Data2View)navigator.CurrentView;navigator.Forward(typeof(Data3View));
var view3 = (Data3View)navigator.CurrentView;Assert.Equal(view3.Data, view2.Data);
navigator.Forward(typeof(Data1View)); // ScopeData disposed
```
* Set to property with same name.
* Even if the name of the property is different, it can be specified by attribute.
* Supports ``IInitializable`` and ``IDisposable`` lifecycle events.### Create custom plugin
Implement the following interface and register to NavigatorConfig.
```csharp
public interface IPlugin
{
// Process when view created
void OnCreate(IPluginContext context, object view, object target);// Process when view closed
void OnClose(IPluginContext context, object view, object target);// Process before stack is changed
void OnNavigatingFrom(IPluginContext context, object view, object target);// Process before stack is changed
void OnNavigatingTo(IPluginContext context, object view, object target);// Process after stack is changed
void OnNavigatedTo(IPluginContext context, object view, object target);
}
```IPluginContext is data store for plugin.
```csharp
public interface IPluginContext
{
void Save(Type type, T value);T Load(Type type);
T LoadOr(Type type, T defaultValue);
T LoadOr(Type type, Func defaultValueFactory);
}
```## Library integration
### IActivator
* Interface is used for object creation.
* Default implementation is ``Activator.CreateInstance()``.
* Customizable by creating the following implementation.```csharp
public interface IActivator
{
object Resolve(Type type);
}
`````Usa.Smart.Navigation.Resolver`` provides an implementation of ``IActivator`` using ``Usa.Smart.Resolver``.
```csharp
// Usage// Config Resolver
var resolver = CreateResolver();// Config Navigator
navigator = new NavigatorConfig()
.UseSomeProvider()
.UseResolver(resolver)
.ToNavigator();
```### IConverter
* Interface is used for type conversion.
* Default implementation uses ``Smart.Converter.IObjectConverter``.
* Customizable by creating the following implementation.```csharp
public interface IConverter
{
object Convert(object value, Type type);
}
```## Link
* [Smart.Resolver](https://github.com/usausa/Smart-Net-Resolver)
## Future
* Animation support required (・ω・)?