Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Xamarin Forms, and Uno / Win UI Applications..
Full Changelog: https://github.com/PrismLibrary/Prism/compare/9.0.271-pre...9.0.401-pre
The Prism team is committed to the long term sustainability of Prism. As a result we have changed the License for Prism moving forward. It is no longer being released under the MIT License. Please visit https://prismlibrary.com for more information on our new license options.
Full Changelog: https://github.com/PrismLibrary/Prism/compare/9.0.264-pre...9.0.271-pre
The Prism team is committed to the long term sustainability of Prism. As a result we have changed the License for Prism moving forward. It is no longer being released under the MIT License. Please visit https://prismlibrary.com for more information on our new license options.
Full Changelog: https://github.com/PrismLibrary/Prism/compare/DNF...9.0.264-pre
This is a procedural release.
Prism is leaving the .NET Foundation. Before making any changes to the Prism repo, we are archiving the current source code which is under the .NET Foundation.
Any code committed after this "Final .NET Foundation Version" release is no longer considered part of the .NET Foundation.
Prism 8.1 is largely a service pack release for Prism 8.0. If upgrading from Prism 7, it is recommended that you skip Prism 8.0 and instead use 8.1. Additionally Prism 8.1 offers a new Prism.Uno.WInUI platform target for those wishing to build either native WinUI3, or Cross Platform WinUI 3 apps with Uno Platform.
Additional updates have been done for Prism.Forms.Regions. This better aligns the API with the original WPF API.
Note that for the new Android GoBack support for Prism.Forms you must update the OnBackPressed in the MainActivity. You may await the call to handle the result. This result could be generated from either a Dialog or Page Navigation result.
public override async void OnBackPressed()
{
var result = await PrismPlatform.OnBackPressed(this);
if (!result.Success)
{
System.Diagnostics.Debugger.Break();
if (result.Exception != null)
{
Console.WriteLine(result.Exception);
}
}
}
It's here, the long awaited Prism 8. This is a huge release and contains a number of breaking changes, bug fixes, new features and even a brand new Platform! So lets officially welcome the Uno Platform to the Prism family of supported platforms!
Beginning with Prism 8.0 all CI packages moving forward will only be available to Sponsors on the Sponsor Connect package feed.
GetErrors
method to help dig in and identify why a type failed to be resolvedAwait
extension to execute callbacks when working inside of a void method without needing to use async void
async void
this allows you to specify a delegate that should be called to handle the exception encountered.This list of changes was auto generated.
This is the Prism 8 Release Candidate! There are lots of changes including some major breaks as noted by the major version bump. Many of the obsolete API's in Prism 7 have now been removed in Prism 8.
async void
without blocking the UI ThreadThis list of changes was auto generated.
This is the initial Prism 8 Preview! There are lots of changes including some major breaks as noted by the major version bump. Many of the obsolete API's in Prism 7 have now been removed in Prism 8.
async void
without blocking the UI ThreadThis list of changes was auto generated.
This is a service release for Prism 7.2. This includes several small bug fixes as noted in the Change Log and changes to make conversions from query string parameters to strong types including Enums more reliable.
This list of changes was auto generated.
Prism 7.2 represents some major fundamental changes. Be sure to read the release notes in full. In addition to adding several new great API's there are some major breaking changes particularly for Xamarin.Forms developers.
After numerous user survey's and interviews it became apparent that the intent of INavigatingAware had been become unclear and that users were actually overwhelmingly asking for a breaking change. INavigatingAware is no longer supported. For those who may be using OnNavigatingTo with INavigationAware this will be most impactful as a behavior change as INavigatingAware has been removed from INavigationAware meaning that it will no longer be called. For those who have implemented INavigatingAware directly you will see a build error. The impact should be minimal by simply renaming all instances of INavigatingAware to Initialize.
IAutoInitialize is designed for those cases where you are passing objects around. By default we do a Non-Case-Sensitive lookup between the Navigation|Dialog Parameters and the Properties in your ViewModel. If one is found we will automatically try to set the property for you.
_navigationService.NavigateAsync("ViewB" ("title", "Hello World"), ("fooBar", "some other value"));
public class ViewBViewModel : IAutoInitialize
{
public string Title { get; set; }
public string FooBar { get; set; }
}
In the above example your ViewModel will be initialized with the values passed in the NavigationParameters or DialogParameters. If these are static variables (meaning the won't change during the lifecycle of your View/ViewModel you would not need to implement INotifyPropertyChanged for them.
public class ViewBViewModel
{
[AutoInitialize(true)
public string Title { get; set; }
[AutoInitialize("fooBar")
public string Foo { get; set; }
}
In this example you'll notice that we have some slight variations where we have added NavigationParameter attributes. The attributes allow you to decorate your properties to make them Required or specify a different name that you will use in your NavigationParameters. Note that if you make a property Required and you fail to pass the parameter this will throw an Exception that you will need to check for in the NavigationResult.
Automatic Registration can be used for either an Application or Module. Note that there is an optional Automatic property. When Automatic is set to true Prism will not look for any attributes but will simply look for any contained types that are a Page type. If there is a Page type it will automatically be registered.
[AutoRegisterForNavigation]
public class App : PrismApplication
{
}
[AutoRegisterForNavigation(Automatic = true)]
public class AwesomeModule : IModule
{
}
The Dialog Service operates by updating the current ContentPage's layout and placing a new View over the top of the existing Content, and then unwinding the changes back to it's original state. This gives the appearance of a Popup similar to what you may see when using Prism.Plugin.Popups but is driven entirely by native Xamarin.Forms.
Custom Alert | Custom Dialog |
---|---|
The Dialog Service provides for a lot of flexibility and customization to help you produce dialogs that look and feel like they belong in your app. This includes an ability to shift the position, change the mask color or provide an entire custom mask layer.
To Start you simply need to implement IDialogAware, and raise the RequestClose
event when you are ready to close the dialog.
public class DemoDialogViewModel : BindableBase, IDialogAware, IAutoInitialize
{
public DemoDialogViewModel()
{
CloseCommand = new DelegateCommand(() => RequestClose(null));
}
private string title = "Message";
public string Title
{
get => title;
set => SetProperty(ref title, value);
}
private string message;
[AutoInitialize(true)] // Makes Message parameter required
public string Message
{
get => message;
set => SetProperty(ref message, value);
}
public DelegateCommand CloseCommand { get; }
public event Action<IDialogParameters> RequestClose;
public bool CanCloseDialog() => true;
public void OnDialogClosed()
{
Console.WriteLine("The Demo Dialog has been closed...");
}
public void OnDialogOpened(IDialogParameters parameters)
{
// No need to do anything as IAutoInitialize will take care of what we need here...
}
}
<?xml version="1.0" encoding="utf-8" ?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="http://prismlibrary.com"
prism:ViewModelLocator.AutowireViewModel="True"
prism:DialogLayout.RelativeWidthRequest="{OnIdiom Default=0.75, Desktop=0.5}"
BackgroundColor="White"
x:Class="HelloWorld.Views.DemoDialog">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<BoxView Color="Black" />
<Label Text="{Binding Title}"
Style="{DynamicResource TitleStyle}"
Margin="20,5"
TextColor="White" />
<Label Text="{Binding Message}"
Margin="20,0,20,10"
Grid.Row="1" />
<Button Text="Ok"
Command="{Binding CloseCommand}"
HorizontalOptions="Center"
Margin="0,0,0,10"
Grid.Row="2"/>
</Grid>
With your View and ViewModel created you now need to register the Dialog to use it. This can be registered in your App.xaml.cs or in a Module.
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog<DemoDialog, DemoDialogViewModel>();
}
Currently, the only way to show any type of dialog with Prism is by using the PopupWindowAction
in combination with System.Windows.Interactivity
. To be honest, I really dislike this approach. It's over complex, highly verbose, difficult to implement, and is very limited. The limitations are covered pretty well in Issue #864
Instead, I created a new IDialogService
API that will replace the PopupWindowAction altogether. This service will allow developers to show any dialog they want either modal, or non-modal, and have complete control over their dialog logic.
The implementation looks like this:
public interface IDialogService
{
void Show(string name, IDialogParameters parameters, Action<IDialogResult> callback);
void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback);
}
The idea here is that Prism will no longer provide any built-in dialogs like Notification or Confirmation. Mainly because the Prism implementations are UGLY and will never match the styling of your beautiful WPF application. So, it's important that you are able to register your own dialogs.
Your dialog view is a simple UserControl that can be designed anyway you please. The only requirement it has a ViewModel that implements IDialogAware
set as it's DataContext. Preferably, it will utilize the ViewModelLocator
<UserControl x:Class="HelloWorld.Dialogs.NotificationDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Width="300" Height="150">
<Grid x:Name="LayoutRoot" Margin="5">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Message}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" TextWrapping="Wrap" />
<Button Command="{Binding CloseDialogCommand}" CommandPrameter="true" Content="OK" Width="75" Height="25" HorizontalAlignment="Right" Margin="0,10,0,0" Grid.Row="1" IsDefault="True" />
</Grid>
</UserControl>
Next you need a ViewModel that implements IDialogAware
which is defined as follows
public interface IDialogAware
{
bool CanCloseDialog();
void OnDialogClosed();
void OnDialogOpened(IDialogParameters parameters);
string Title { get; set; }
event Action<IDialogResult> RequestClose;
}
Here is a simple example of what an IDialogAware
ViewModel may look like.
public class NotificationDialogViewModel : BindableBase, IDialogAware
{
private DelegateCommand<string> _closeDialogCommand;
public DelegateCommand<string> CloseDialogCommand =>
_closeDialogCommand ?? (_closeDialogCommand = new DelegateCommand<string>(CloseDialog));
private string _message;
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value); }
}
private string _title = "Notification";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public event Action<IDialogResult> RequestClose;
protected virtual void CloseDialog(string parameter)
{
ButtonResult result = ButtonResult.None;
if (parameter?.ToLower() == "true")
result = ButtonResult.OK;
else if (parameter?.ToLower() == "false")
result = ButtonResult.Cancel;
RaiseRequestClose(new DialogResult(result));
}
public virtual void RaiseRequestClose(IDialogResult dialogResult)
{
RequestClose?.Invoke(dialogResult);
}
public virtual bool CanCloseDialog()
{
return true;
}
public virtual void OnDialogClosed()
{
}
public virtual void OnDialogOpened(IDialogParameters parameters)
{
Message = parameters.GetValue<string>("message");
}
}
To register a dialog, you must have a View (UserControl) and a corresponding ViewModel (which must implement IDialogAware
). In the RegisterTypes
method, simply register your dialog like you would any other service by using the IContainterRegistery.RegisterDialog
method.
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog<NotificationDialog, NotificationDialogViewModel>();
}
To use the dialog service you simply ask for the service in your VM ctor.
public MainWindowViewModel(IDialogService dialogService)
{
_dialogService = dialogService;
}
Then call either Show
or ShowDialog
providing the name of the dialog, any parameters your dialogs requires, and then handle the result via a call back
private void ShowDialog()
{
var message = "This is a message that should be shown in the dialog.";
//using the dialog service as-is
_dialogService.ShowDialog("NotificationDialog", new DialogParameters($"message={message}"), r =>
{
if (r.Result == ButtonResult.None)
Title = "Result is None";
else if (r.Result == ButtonResult.OK)
Title = "Result is OK";
else if (r.Result == ButtonResult.Cancel)
Title = "Result is Cancel";
else
Title = "I Don't know what you did!?";
});
}
The intent of the dialog API is not to try and guess exactly what type of parameters your need for all of your dialogs, but rather to just create and show the dialogs. To simplify common dialogs in your application the guidance will be to create an extension methods to simplify your applications dialogs.
For example:
public static class DialogServiceExtensions
{
public static void ShowNotification(this IDialogService dialogService, string message, Action<IDialogResult> callBack)
{
dialogService.ShowDialog("NotificationDialog", new DialogParameters($"message={message}"), callBack);
}
}
Then to call your Notifications use the new and improved API that you created specifically for your app.
_dialogService.ShowNotification(message, r =>
{
if (r.Result == ButtonResult.None)
Title = "Result is None";
else if (r.Result == ButtonResult.OK)
Title = "Result is OK";
else if (r.Result == ButtonResult.Cancel)
Title = "Result is Cancel";
else
Title = "I Don't know what you did!?";
});
It's very common to be using a third-party control vendor such as Infragistics. In these cases, you may want to replace the standard WPF Window control that hosts the dialogs with a custom Window class such as the Infragistics XamRibbonWindow control.
In this case, just create your custom Window, and implement the IDialogWindow
interface:
public partial class MyRibbonWindow: XamRibbonWindow, IDialogWindow
{
public IDialogResult Result { get; set; }
….
}
Then register your dialog window with the IContainerRegistry
.
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialogWindow<MyRibbonWindow>();
}
You can control the properties of the DialogWindow by using a style via an attatched property on the Dialog UserControl
<prism:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="prism:Dialog.WindowStartupLocation" Value="CenterScreen" />
<Setter Property="ResizeMode" Value="NoResize"/>
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="SizeToContent" Value="WidthAndHeight"/>
</Style>
</prism:Dialog.WindowStyle>
To clarify, this is to replace the PopupWindowAction. I want to remove that mess completely from Prism
This list of changes was auto generated.