diff --git a/Source/Views/MultiPageViewForm.cs b/Source/Views/MultiPageViewForm.cs
index 4c3a034..61c55d8 100644
--- a/Source/Views/MultiPageViewForm.cs
+++ b/Source/Views/MultiPageViewForm.cs
@@ -140,7 +140,7 @@ namespace Nuclex.Windows.Forms.Views {
/// Discovers the container control used to host the child views
/// The container control is which the child views will be hosted
///
- /// This is supposed to be overriden by the user, simply returning the container
+ /// This is supposed to be overridden by the user, simply returning the container
/// control that should host the page views. If it isn't, however, we use some
/// heuristics to figure out the most likely candidate: it should be a container,
/// and it should cover most of the window's client area.
diff --git a/Source/Views/ViewControl.cs b/Source/Views/ViewControl.cs
index 329f673..7b39b6b 100644
--- a/Source/Views/ViewControl.cs
+++ b/Source/Views/ViewControl.cs
@@ -85,12 +85,23 @@ namespace Nuclex.Windows.Forms.Views {
}
}
}
+#else
+ /// Called when the control's data context has changed
+ /// Not used
+ protected override void OnDataContextChanged(EventArgs arguments) {
+ object oldDataContext = this.dataContext;
+ this.dataContext = base.DataContext;
+
+ if(this.dataContext != oldDataContext) {
+ OnDataContextChanged(this, oldDataContext, this.dataContext);
+ }
+ }
#endif
-#if !NET8_0_OR_GREATER
+ // NOTE: Careful! On .NET 8.0, the Control class has its own DataContext,
+ // but this one will be used to be able to report the previous one.
/// Active data binding target, can be null
private object dataContext;
-#endif
/// Delegate for the OnViewModelPropertyChanged() method
private PropertyChangedEventHandler onViewModelPropertyChangedDelegate;
diff --git a/Source/Views/ViewForm.cs b/Source/Views/ViewForm.cs
index db8d242..d09c407 100644
--- a/Source/Views/ViewForm.cs
+++ b/Source/Views/ViewForm.cs
@@ -42,20 +42,6 @@ namespace Nuclex.Windows.Forms.Views {
this.onViewModelPropertyChangedDelegate = OnViewModelPropertyChanged;
}
-#if !NET8_0_OR_GREATER
- /// Provides the data binding target for the view
- public object DataContext {
- get { return this.dataContext; }
- set {
- if(value != this.dataContext) {
- object oldDataContext = this.dataContext;
- this.dataContext = value;
- OnDataContextChanged(this, oldDataContext, value);
- }
- }
- }
-#endif
-
/// Called when the window's data context is changed
/// Window whose data context was changed
/// Data context that was previously used
@@ -88,9 +74,34 @@ namespace Nuclex.Windows.Forms.Views {
) { }
#if !NET8_0_OR_GREATER
+ /// Provides the data binding target for the view
+ public object DataContext {
+ get { return this.dataContext; }
+ set {
+ if(value != this.dataContext) {
+ object oldDataContext = this.dataContext;
+ this.dataContext = value;
+ OnDataContextChanged(this, oldDataContext, value);
+ }
+ }
+ }
+#else
+ /// Called when the control's data context has changed
+ /// Not used
+ protected override void OnDataContextChanged(EventArgs arguments) {
+ object oldDataContext = this.dataContext;
+ this.dataContext = base.DataContext;
+
+ if(this.dataContext != oldDataContext) {
+ OnDataContextChanged(this, oldDataContext, this.dataContext);
+ }
+ }
+#endif
+
+ // NOTE: Careful! On .NET 8.0, the Control class has its own DataContext,
+ // but this one will be used to be able to report the previous one.
/// Active data binding target, can be null
private object dataContext;
-#endif
/// Delegate for the OnViewModelPropertyChanged() method
private PropertyChangedEventHandler onViewModelPropertyChangedDelegate;
diff --git a/Source/WindowManager.cs b/Source/WindowManager.cs
index b83c448..76ae42b 100644
--- a/Source/WindowManager.cs
+++ b/Source/WindowManager.cs
@@ -363,14 +363,20 @@ namespace Nuclex.Windows.Forms {
return Activator.CreateInstance(type);
}
- /// Creates an instance of the specified type in a new scope
- /// Type an instance will be created of
- /// The created instance and the scope in which it lives
+ /// Creates a new scope in which window-specific instances live
+ ///
+ /// A new scope in which scoped services requested by the window's view model
+ /// will live
+ ///
///
- /// This is identical to but, if used together
- /// with a dependency injector, should also create a service scope. This way,
- /// an implicit service scope will cover the lifetime of a view model and
- /// any non-singleton services will use new instances, avoiding, for example,
+ /// If you do not override this method, services will be constructed through
+ /// the normal method (which actually may not
+ /// work without managing your own service scope in case your dependency
+ /// injector supports scopes and some of your services are scoped). By
+ /// overriding this method, you can automatically cause a new scope to be
+ /// created for each window or dialog. That way, an implicit service scope
+ /// will cover the lifetime of each window and its view model and any
+ /// non-singleton services will use new instances, avoiding, for example,
/// that multiple dialogs access the same database connection simultaneously.
///
protected virtual IWindowScope CreateWindowScope() {
@@ -464,6 +470,9 @@ namespace Nuclex.Windows.Forms {
///
/// Control that will dispose a scope when it is itself disposed
///
+ ///
+ /// Scope that will be disposed together with the control
+ ///
private void setupScopeDisposal(Control control, IWindowScope scope) {
if(!ReferenceEquals(scope, this.windowManagerAsScope)) {
IDisposable disposableScope = scope as IDisposable;