Closed amkuchta closed 6 years ago
Hey @amkuchta! In my work project, I am indeed using MVVM. Well, for the most part, anyway (grumble grumble need to refactor). I'm using data binding for the notification manager, so my code still applies.
I'm indeed having problems getting your solution to compile, mostly because MahApps doesn't want to build due to not finding that Nuget reference. Don't I have to add some reference to the Appveyor build or something? Could you please point me in the right direction?
I'm not sure without poking around more myself, but does your notification manager GUI item have any width? Have you looked at it in WPF Snoop? I mean, I see that you have it set up in a Grid, but since the project won't build, I'm having a hard time visualizing what it's doing.
Here's the applicable code from my work project if it's helpful:
MainWindow.xaml
<Grid Grid.Row="0" Grid.RowSpan="3" ClipToBounds="True" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="#AACCCCCC" Grid.Column="0" Grid.ColumnSpan="3"
Visibility="{Binding PreventWindowInteraction, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Border Grid.Column="1">
<notification:NotificationMessageContainer Manager="{Binding NotificationManager}" />
</Border>
<Label Content="doesn't matter for this sample code"
FontSize="36" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center"
FontStyle="Italic"
Visibility="{Binding AThingForWork, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>
ViewModel
private INotificationMessageManager _notificationManager;
...
public MainWindowViewModel()
{
...
NotificationManager = new NotificationMessageManager();
}
...
public INotificationMessageManager NotificationManager
{
get { return _notificationManager; }
set { _notificationManager = value; RaisePropertyChangedEvent(nameof(NotificationManager)); }
}
...
public NotificationMessageBuilder GetBuilderBase(string message, int autoDismissSeconds = -1)
{
var builder =
NotificationManager...
return builder;
}
MainWindow.xaml.cs (I know, I know...long story. Maybe someday ™️ I can refactor to avoid this)
_dataContext.GetBuilderBase(
string.Format("blah blah blah"))
.WithButton("Btn1", button => { Void(); })
.WithButton("Btn2", button => {
Void();
})
.Dismiss().WithButton("Close", button => { })
.Queue();
So technically I'm queuing it from the code behind, but the actual NotificationManager
is in the view model.
I was also working on a branch for including animations with this lib, but didn't get to finish it. If it's helpful, check out the top two commits on this branch.
@Deadpikle thanks for the response! Yes, I am pulling my MA.M build from Appveyor - the source is https://ci.appveyor.com/nuget/mahapps.metro, and can be added in the Options window (Options -> NuGet Package Manager -> Package Sources). You may also get an error for SQLite - let me know if you do and I can get you through that, too (I had to have the SQLite DLLs set up to do a "portable" install, as users cannot actually install the application on their machines).
As far as the Grid
width goes, I do not have one specifically set, but shouldn't it just follow the width of the window? I also saw that you have the NotificationMessageContainer
wrapped in a Border
- any reason for this? (I tried it, and it still didn't work... grrrr). Also, as a side note, I do not currently have INotifyPropertyChanged
implemented for NotificationMessageManager
, though I did try this as well and it didn't have any effect.
I'll try running it against WPF Snoop - thanks for the hint on that! Let me know if you can get my solution built!
@amkuchta Yeah, it's a bug. Since you're doing CreateMessage
call from VM constructor, the message container in the view isn't yet bound to the manager.
NotificationMessageContainer
only listens for OnMessageQueued
and that's not triggered when you give it a manager with message already in queue.
Here after attaching event handlers, ManagerOnOnMessageDismissed
should be called for all existing messages and ManagerOnOnMessageQueued
for each message from the new manager.
Could this be it? Can you test this by not calling CreateMessage
from constructor but for example on view Loaded
?
Eureka! That was it! My updated code:
...
<!--Added an event trigger on the window (which requires an additional namespace for interactivity)-->
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
...
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LaunchStigNotificationCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
...
<!--Everything else stays the same with regards to the NotificationMessageContainer-->
...
...
// Moved the logic to create the NotificationMessage into its own function, which is launched via the command bound above
public RelayCommand LaunchStigNotificationCommand
{ get { return new RelayCommand(LaunchStigNotification); } }
private void LaunchStigNotification()
{
try
{
NotificationMessageManager.CreateMessage()
.Accent("#1751C3")
.Animates(true)
.AnimationInDuration(0.75)
.AnimationOutDuration(0.75)
.HasBadge("Info")
.HasMessage("Please ingest the latest STIG Compilation Library on the settings page.")
.Dismiss().WithButton("Dismiss", button => { })
.Queue();
}
catch (Exception exception)
{
log.Error(string.Format("Unable to launch STIG library ingestion notification."));
log.Debug("Exception details:", exception);
}
}
...
Hopefully this approach helps you when you decide to refactor your application :wink: Thank you for the help!!!
@amkuchta So is this resolved? Can I close this issue?
@AleksandarDev it sure is! I'll go ahead and close it out, thank you!
Unrelated - how open are you to accepting PRs for enhancements, both to the code (I'd like to tinker with enhancing the control a bit) and to the documentation (perhaps using the wiki)? I love these controls, and I'd like to contribute to them in some way. Do you require issues be opened to tie all PRs back to for tracking?
@amkuchta An issue should be opened before commiting to the feature so that we have a place to discuss issues/problems that may occur. Other than that, we accept all PR's for non-breaking changes w/o question. But if there is a real need to break existing behaviour, we can work out the release plan for that too, but that should be discussed on per-issue basis.
For the wiki, can we have the docs in the source? I'm not really sure where GitHub's wiki stores the docs and how can we control the access.
@AleksandarDev GitHub treats the wiki just like any other source - you can clone it and submit updates / PRs via git, which would then have to be reviewed / approved before they are accepted.
Synopsis
This may be related to #1 , but I am having issues with getting a notification to launch using an MVVM pattern. Relevant code is below; if you'd like to take a look at the application yourself, please feel free to clone from here - if you run into any issues getting the application to start, let me know, you may need to work some magic to get the application to run in Visual Studio.
View (/View/UI/DevWindow.xaml)
ViewModel (/ViewModel/MainViewModel.cs)
Debugging
Running through a quick debug,
NotificationMessageManager
is properly instantiated and the message is created and associated to it. Similarly, looking at the visual tree, theNotificationMessageContainer
exists, but is empty. Finally, no error messages are generated and logged, and my output window isn't throwing anything concerning this control, so I have nothing to suggest that anything is failing.Thanks in advance! I love the way this looks, so I am really hoping to be able to utilize the control. However, I am following a strict "no code behind" policy, which I would rather not violate.