La mia applicazione è un progetto WPF implementato in C # .NET (4.5) che utilizza un'architettura MVVM senza code-behind nella vista. Per eliminare l'accoppiamento tra View e ViewModel sto implementando alcuni comportamenti specifici di WPF come DependencyProperties personalizzate che possono essere associati a proprietà 'semplici' esposte dal ViewModel.
L'assieme View ora ha diverse di queste proprietà Dependency vincolate dal 'Windows' di livello superiore nella vista. Non vedo alcun motivo ovvio per riunirli in una singola classe "Controller", a parte questo quando faccio così il codice diventa improvvisamente più bello, ma così facendo si introduce un accoppiamento non necessario tra queste proprietà semplicemente perché potrebbero essere vincolati da un Vista di primo livello perché non tutti gli oggetti ViewModel richiedono tutti i comportamenti.
Devo sacrificare una riduzione dell'accoppiamento richiedendo che gli oggetti ViewModel di livello superiore espongano una proprietà "Controller" coesiva per la vista da associare a una singola DependencyProperty personalizzata? Sarebbe meglio implementare proprietà DependencyProperties personalizzate multiple, monouso per ciascuno dei comportamenti? C'è un appropaco completamente diverso che potrei usare, come fornire una sorta di "container di comportamento"?
Approccio a controller singolo:
using System;
using System.Threading;
using System.Windows;
using FrameworkMVVM.BindingControllers; // For TopLevelViewController
namespace FrameworkMVVM.ViewBehaviours
{
public static class WindowBindableProperties
{
// One property that encapsulates the behaviours in a controller class
#region WindowControllerProperty
private static DependencyProperty _windowControllerProperty =
DependencyProperty.RegisterAttached
(
"WindowController",
typeof(TopLevelViewController),
typeof(WindowBindableProperties),
new PropertyMetadata(null, WindowControllerPropertyChanged)
);
public static DependencyProperty WindowControllerProperty
{ get { return _windowControllerProperty; } }
private static void WindowControllerPropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
// Hook the events, EventHandlers, SynchronizationContext,
// DialogResult, etc. here.
}
#endregion
}
}
Approccio a più proprietà:
using System;
using System.Threading;
using System.Windows;
namespace FrameworkMVVM.ViewBehaviours
{
public static class WindowBindableProperties
{
// Multiple properties, one for each behaviour.
#region CloseViewEventProperty
private static DependencyProperty _closeViewEventProperty =
DependencyProperty.RegisterAttached
(
"CloseViewEvent",
typeof(EventHandler),
typeof(WindowBindableProperties),
new PropertyMetadata(null, CloseViewEventPropertyChanged)
);
// The rest of the CloseViewEvent implementation goes here.
#endregion
#region DialogResultProperty
private static DependencyProperty _dialogResultProperty =
DependencyProperty.RegisterAttached
(
"DialogResultProperty",
typeof(Boolean?),
typeof(WindowBindableProperties),
new PropertyMetadata(null, DialogResultPropertyChanged)
);
// The rest of the DialogResultProperty implementation goes here.
#endregion
#region ViewContextProperty
private static DependencyProperty _viewContextProperty =
DependencyProperty.RegisterAttached
(
"ViewContextProperty",
typeof(SynchronizationContext),
typeof(WindowBindableProperties),
new PropertyMetadata(null, ViewContextPropertyChanged)
);
// The rest of the ViewContextProperty implementation goes here.
#endregion
// Etc., etc., etc..
}
}