mirror of https://github.com/AMT-Cheif/Stylet.git
Get rid of the static ViewLocator and ViewModelBinder, and replace with the singleton ViewManager
This commit is contained in:
parent
1607dc9ad3
commit
40c9d4ed88
|
@ -26,6 +26,7 @@ namespace Stylet
|
|||
{
|
||||
builder.Autobind(AssemblySource.Assemblies);
|
||||
builder.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
|
||||
builder.Bind<IViewManager>().To<ViewManager>().InSingletonScope();
|
||||
}
|
||||
|
||||
protected override object GetInstance(Type service, string key = null)
|
||||
|
|
|
@ -71,8 +71,7 @@
|
|||
<Compile Include="StyletIoC\StyletIoCContainer.cs" />
|
||||
<Compile Include="StyletIoC\UnboundGeneric.cs" />
|
||||
<Compile Include="View.cs" />
|
||||
<Compile Include="ViewLocator.cs" />
|
||||
<Compile Include="ViewModelBinder.cs" />
|
||||
<Compile Include="ViewManager.cs" />
|
||||
<Compile Include="WindowManager.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -41,37 +41,10 @@ namespace Stylet
|
|||
|
||||
// Using a DependencyProperty as the backing store for Model. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty ModelProperty =
|
||||
DependencyProperty.RegisterAttached("Model", typeof(object), typeof(View), new PropertyMetadata(null, OnModelChanged));
|
||||
DependencyProperty.RegisterAttached("Model", typeof(object), typeof(View), new PropertyMetadata(null, (d, e) => IoC.Get<IViewManager>().OnModelChanged(d, e) ));
|
||||
|
||||
|
||||
private static void OnModelChanged(DependencyObject targetLocation, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.OldValue == e.NewValue)
|
||||
return;
|
||||
|
||||
if (e.NewValue != null)
|
||||
{
|
||||
UIElement view;
|
||||
var viewModelAsViewAware = e.NewValue as IViewAware;
|
||||
if (viewModelAsViewAware != null && viewModelAsViewAware.View != null)
|
||||
{
|
||||
view = viewModelAsViewAware.View;
|
||||
}
|
||||
else
|
||||
{
|
||||
view = ViewLocator.LocateForModel(e.NewValue);
|
||||
ViewModelBinder.Bind(view, e.NewValue);
|
||||
}
|
||||
|
||||
SetContentProperty(targetLocation, view);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetContentProperty(targetLocation, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetContentProperty(DependencyObject targetLocation, UIElement view)
|
||||
public static void SetContentProperty(DependencyObject targetLocation, UIElement view)
|
||||
{
|
||||
var type = targetLocation.GetType();
|
||||
var contentProperty = Attribute.GetCustomAttributes(type, true).OfType<ContentPropertyAttribute>().FirstOrDefault() ?? DefaultContentProperty;
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Stylet
|
||||
{
|
||||
public static class ViewLocator
|
||||
{
|
||||
public static UIElement LocateForModel(object model)
|
||||
{
|
||||
var modelName = model.GetType().FullName;
|
||||
var viewName = Regex.Replace(modelName, @"ViewModel", "View");
|
||||
// TODO: This might need some more thinking
|
||||
var viewType = AssemblySource.Assemblies.SelectMany(x => x.GetExportedTypes()).FirstOrDefault(x => x.FullName == viewName);
|
||||
|
||||
if (viewType == null)
|
||||
throw new Exception(String.Format("Unable to find a View with type {0}", viewName));
|
||||
|
||||
if (viewType.IsInterface || viewType.IsAbstract || !typeof(UIElement).IsAssignableFrom(viewType))
|
||||
throw new Exception(String.Format("Found type for view : {0}, but it wasn't a class derived from UIElement", viewType.Name));
|
||||
|
||||
var view = (UIElement)IoC.GetInstance(viewType, null);
|
||||
|
||||
// If it doesn't have a code-behind, this won't be called
|
||||
var initializer = viewType.GetMethod("InitializeComponent", BindingFlags.Public | BindingFlags.Instance);
|
||||
if (initializer != null)
|
||||
initializer.Invoke(view, null);
|
||||
|
||||
return (UIElement)view;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Stylet
|
||||
{
|
||||
public interface IViewManager
|
||||
{
|
||||
void OnModelChanged(DependencyObject targetLocation, DependencyPropertyChangedEventArgs e);
|
||||
UIElement LocateViewForModel(object model);
|
||||
void BindViewToModel(UIElement view, object viewModel);
|
||||
}
|
||||
|
||||
public class ViewManager : IViewManager
|
||||
{
|
||||
public virtual void OnModelChanged(DependencyObject targetLocation, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.OldValue == e.NewValue)
|
||||
return;
|
||||
|
||||
if (e.NewValue != null)
|
||||
{
|
||||
UIElement view;
|
||||
var viewModelAsViewAware = e.NewValue as IViewAware;
|
||||
if (viewModelAsViewAware != null && viewModelAsViewAware.View != null)
|
||||
{
|
||||
view = viewModelAsViewAware.View;
|
||||
}
|
||||
else
|
||||
{
|
||||
view = this.LocateViewForModel(e.NewValue);
|
||||
this.BindViewToModel(view, e.NewValue);
|
||||
}
|
||||
|
||||
View.SetContentProperty(targetLocation, view);
|
||||
}
|
||||
else
|
||||
{
|
||||
View.SetContentProperty(targetLocation, null);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual UIElement LocateViewForModel(object model)
|
||||
{
|
||||
var modelName = model.GetType().FullName;
|
||||
var viewName = Regex.Replace(modelName, @"ViewModel", "View");
|
||||
// TODO: This might need some more thinking
|
||||
var viewType = AssemblySource.Assemblies.SelectMany(x => x.GetExportedTypes()).FirstOrDefault(x => x.FullName == viewName);
|
||||
|
||||
if (viewType == null)
|
||||
throw new Exception(String.Format("Unable to find a View with type {0}", viewName));
|
||||
|
||||
if (viewType.IsInterface || viewType.IsAbstract || !typeof(UIElement).IsAssignableFrom(viewType))
|
||||
throw new Exception(String.Format("Found type for view : {0}, but it wasn't a class derived from UIElement", viewType.Name));
|
||||
|
||||
var view = (UIElement)IoC.GetInstance(viewType, null);
|
||||
|
||||
// If it doesn't have a code-behind, this won't be called
|
||||
var initializer = viewType.GetMethod("InitializeComponent", BindingFlags.Public | BindingFlags.Instance);
|
||||
if (initializer != null)
|
||||
initializer.Invoke(view, null);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public virtual void BindViewToModel(UIElement view, object viewModel)
|
||||
{
|
||||
View.SetTarget(view, viewModel);
|
||||
|
||||
var viewAsFrameworkElement = view as FrameworkElement;
|
||||
if (viewAsFrameworkElement != null)
|
||||
viewAsFrameworkElement.DataContext = viewModel;
|
||||
|
||||
var viewModelAsViewAware = viewModel as IViewAware;
|
||||
if (viewModelAsViewAware != null)
|
||||
viewModelAsViewAware.AttachView(view);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Stylet
|
||||
{
|
||||
public static class ViewModelBinder
|
||||
{
|
||||
public static void Bind(UIElement view, object viewModel)
|
||||
{
|
||||
View.SetTarget(view, viewModel);
|
||||
|
||||
var viewAsFrameworkElement = view as FrameworkElement;
|
||||
if (viewAsFrameworkElement != null)
|
||||
viewAsFrameworkElement.DataContext = viewModel;
|
||||
|
||||
var viewModelAsViewAware = viewModel as IViewAware;
|
||||
if (viewModelAsViewAware != null)
|
||||
viewModelAsViewAware.AttachView(view);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,11 +30,13 @@ namespace Stylet
|
|||
|
||||
private Window CreateWindow(object viewModel, bool isDialog)
|
||||
{
|
||||
var view = ViewLocator.LocateForModel(viewModel) as Window;
|
||||
var viewManager = IoC.Get<IViewManager>();
|
||||
|
||||
var view = viewManager.LocateViewForModel(viewModel) as Window;
|
||||
if (view == null)
|
||||
throw new Exception(String.Format("Tried to show {0} as a window, but it isn't a Window", view.GetType().Name));
|
||||
|
||||
ViewModelBinder.Bind(view, viewModel);
|
||||
viewManager.BindViewToModel(view, viewModel);
|
||||
|
||||
var haveDisplayName = viewModel as IHaveDisplayName;
|
||||
if (haveDisplayName != null)
|
||||
|
|
Loading…
Reference in New Issue