mirror of https://github.com/AMT-Cheif/Stylet.git
Simplify IViewManager, by aligning it to what someone actually wants the ViewManager to do
This commit is contained in:
parent
b53d0f5195
commit
60aca05dd2
|
@ -21,18 +21,11 @@ namespace Stylet
|
|||
void OnModelChanged(DependencyObject targetLocation, object oldValue, object newValue);
|
||||
|
||||
/// <summary>
|
||||
/// Given a ViewModel instance, locate its View type (using LocateViewForModel), instantiates and initializes it
|
||||
/// Create a View for the given ViewModel, and bind the two together
|
||||
/// </summary>
|
||||
/// <param name="model">ViewModel to locate and instantiate the View for</param>
|
||||
/// <returns>Instantiated and setup view</returns>
|
||||
UIElement CreateAndSetupViewForModel(object model);
|
||||
|
||||
/// <summary>
|
||||
/// Given an instance of a ViewModel and an instance of its View, bind the two together
|
||||
/// </summary>
|
||||
/// <param name="view">View to bind to the ViewModel</param>
|
||||
/// <param name="viewModel">ViewModel to bind the View to</param>
|
||||
void BindViewToModel(UIElement view, object viewModel);
|
||||
/// <param name="model">ViewModel to create a Veiw for</param>
|
||||
/// <returns>Newly created View, bound to the given ViewModel</returns>
|
||||
UIElement CreateAndBindViewForModel(object model);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -61,8 +54,7 @@ namespace Stylet
|
|||
}
|
||||
else
|
||||
{
|
||||
view = this.CreateAndSetupViewForModel(newValue);
|
||||
this.BindViewToModel(view, newValue);
|
||||
view = this.CreateAndBindViewForModel(newValue);
|
||||
}
|
||||
|
||||
View.SetContentProperty(targetLocation, view);
|
||||
|
@ -73,6 +65,20 @@ namespace Stylet
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a View for the given ViewModel, and bind the two together
|
||||
/// </summary>
|
||||
/// <param name="model">ViewModel to create a Veiw for</param>
|
||||
/// <returns>Newly created View, bound to the given ViewModel</returns>
|
||||
public virtual UIElement CreateAndBindViewForModel(object model)
|
||||
{
|
||||
// Need to bind before we initialize the view
|
||||
// Otherwise e.g. the Command bindings get evaluated (by InitializeComponent) but the ActionTarget hasn't been set yet
|
||||
var view = this.CreateViewForModel(model);
|
||||
this.BindViewToModel(view, model);
|
||||
return view;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given the expected name for a view, locate its type (or throw an exception if a suitable type couldn't be found)
|
||||
/// </summary>
|
||||
|
@ -102,11 +108,11 @@ namespace Stylet
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a ViewModel instance, locate its View type (using LocateViewForModel), instantiates and initializes it, and binds it to the ViewModel (using BindViewToModel)
|
||||
/// Given a ViewModel instance, locate its View type (using LocateViewForModel), and instantiates it
|
||||
/// </summary>
|
||||
/// <param name="model">ViewModel to locate and instantiate the View for</param>
|
||||
/// <returns>Instantiated and setup view</returns>
|
||||
public virtual UIElement CreateAndSetupViewForModel(object model)
|
||||
protected virtual UIElement CreateViewForModel(object model)
|
||||
{
|
||||
var viewType = this.LocateViewForModel(model.GetType());
|
||||
|
||||
|
@ -123,12 +129,12 @@ namespace Stylet
|
|||
return view;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Given an instance of a ViewModel and an instance of its View, bind the two together
|
||||
/// </summary>
|
||||
/// <param name="view">View to bind to the ViewModel</param>
|
||||
/// <param name="viewModel">ViewModel to bind the View to</param>
|
||||
public virtual void BindViewToModel(UIElement view, object viewModel)
|
||||
protected virtual void BindViewToModel(UIElement view, object viewModel)
|
||||
{
|
||||
View.SetActionTarget(view, viewModel);
|
||||
|
||||
|
|
|
@ -68,13 +68,11 @@ namespace Stylet
|
|||
/// <returns>Window which was created and set up</returns>
|
||||
protected virtual Window CreateWindow(object viewModel, bool isDialog)
|
||||
{
|
||||
var view = this.viewManager.CreateAndSetupViewForModel(viewModel);
|
||||
var view = this.viewManager.CreateAndBindViewForModel(viewModel);
|
||||
var window = view as Window;
|
||||
if (window == null)
|
||||
throw new ArgumentException(String.Format("Tried to show {0} as a window, but it isn't a Window", view == null ? "(null)" : view.GetType().Name));
|
||||
|
||||
this.viewManager.BindViewToModel(window, viewModel);
|
||||
|
||||
var haveDisplayName = viewModel as IHaveDisplayName;
|
||||
if (haveDisplayName != null && BindingOperations.GetBindingBase(window, Window.TitleProperty) == null)
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<DockPanel LastChildFill="False">
|
||||
<GroupBox DockPanel.Dock="Top" Header="ShowDialog and DialogResult" Padding="10">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Command="{s:Action ShowDialogAndDialogResult}">Show Dialog</Button>
|
||||
<Button Command="{s:Action ShowDialogAndDialogResult, NullTarget=Throw}">Show Dialog</Button>
|
||||
<TextBlock Margin="50,0,0,0">Result: </TextBlock>
|
||||
<TextBlock Margin="10,0,0,0" Text="{Binding ShowDialogAndDialogResultDialogResult}"/>
|
||||
</StackPanel>
|
||||
|
|
|
@ -28,11 +28,24 @@ namespace StyletUnitTests
|
|||
private abstract class AC1 { }
|
||||
private class C1 { }
|
||||
|
||||
private class AccessibleViewManager : ViewManager
|
||||
{
|
||||
public new UIElement CreateViewForModel(object model)
|
||||
{
|
||||
return base.CreateViewForModel(model);
|
||||
}
|
||||
|
||||
public new void BindViewToModel(UIElement view, object viewModel)
|
||||
{
|
||||
base.BindViewToModel(view, viewModel);
|
||||
}
|
||||
}
|
||||
|
||||
private class CreatingAndBindingViewManager : ViewManager
|
||||
{
|
||||
public UIElement View;
|
||||
public object RequestedModel;
|
||||
public override UIElement CreateAndSetupViewForModel(object model)
|
||||
protected override UIElement CreateViewForModel(object model)
|
||||
{
|
||||
this.RequestedModel = model;
|
||||
return this.View;
|
||||
|
@ -40,7 +53,7 @@ namespace StyletUnitTests
|
|||
|
||||
public UIElement BindViewToModelView;
|
||||
public object BindViewtoModelViewModel;
|
||||
public override void BindViewToModel(UIElement view, object viewModel)
|
||||
protected override void BindViewToModel(UIElement view, object viewModel)
|
||||
{
|
||||
this.BindViewToModelView = view;
|
||||
this.BindViewtoModelViewModel = viewModel;
|
||||
|
@ -156,13 +169,13 @@ namespace StyletUnitTests
|
|||
var viewManager = new LocatingViewManager();
|
||||
|
||||
viewManager.LocatedViewType = typeof(I1);
|
||||
Assert.Throws<StyletViewLocationException>(() => viewManager.CreateAndSetupViewForModel(new object()));
|
||||
Assert.Throws<StyletViewLocationException>(() => viewManager.CreateAndBindViewForModel(new object()));
|
||||
|
||||
viewManager.LocatedViewType = typeof(AC1);
|
||||
Assert.Throws<StyletViewLocationException>(() => viewManager.CreateAndSetupViewForModel(new object()));
|
||||
Assert.Throws<StyletViewLocationException>(() => viewManager.CreateAndBindViewForModel(new object()));
|
||||
|
||||
viewManager.LocatedViewType = typeof(C1);
|
||||
Assert.Throws<StyletViewLocationException>(() => viewManager.CreateAndSetupViewForModel(new object()));
|
||||
Assert.Throws<StyletViewLocationException>(() => viewManager.CreateAndBindViewForModel(new object()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -178,7 +191,7 @@ namespace StyletUnitTests
|
|||
var viewManager = new LocatingViewManager();
|
||||
viewManager.LocatedViewType = typeof(TestView);
|
||||
|
||||
var returnedView = viewManager.CreateAndSetupViewForModel(new object());
|
||||
var returnedView = viewManager.CreateAndBindViewForModel(new object());
|
||||
|
||||
Assert.True(view.InitializeComponentCalled);
|
||||
Assert.AreEqual(view, returnedView);
|
||||
|
@ -197,7 +210,7 @@ namespace StyletUnitTests
|
|||
var viewManager = new LocatingViewManager();
|
||||
viewManager.LocatedViewType = typeof(UIElement);
|
||||
|
||||
var returnedView = viewManager.CreateAndSetupViewForModel(new object());
|
||||
var returnedView = viewManager.CreateAndBindViewForModel(new object());
|
||||
|
||||
Assert.AreEqual(view, returnedView);
|
||||
}
|
||||
|
@ -207,7 +220,8 @@ namespace StyletUnitTests
|
|||
{
|
||||
var view = new UIElement();
|
||||
var model = new object();
|
||||
this.viewManager.BindViewToModel(view, model);
|
||||
var viewManager = new AccessibleViewManager();
|
||||
viewManager.BindViewToModel(view, model);
|
||||
|
||||
Assert.AreEqual(model, View.GetActionTarget(view));
|
||||
}
|
||||
|
@ -217,7 +231,8 @@ namespace StyletUnitTests
|
|||
{
|
||||
var view = new FrameworkElement();
|
||||
var model = new object();
|
||||
this.viewManager.BindViewToModel(view, model);
|
||||
var viewManager = new AccessibleViewManager();
|
||||
viewManager.BindViewToModel(view, model);
|
||||
|
||||
Assert.AreEqual(model, view.DataContext);
|
||||
}
|
||||
|
@ -227,7 +242,8 @@ namespace StyletUnitTests
|
|||
{
|
||||
var view = new UIElement();
|
||||
var model = new Mock<IViewAware>();
|
||||
this.viewManager.BindViewToModel(view, model.Object);
|
||||
var viewManager = new AccessibleViewManager();
|
||||
viewManager.BindViewToModel(view, model.Object);
|
||||
|
||||
model.Verify(x => x.AttachView(view));
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace StyletUnitTests
|
|||
public void CreateWindowAsksViewManagerForView()
|
||||
{
|
||||
var model = new object();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model)).Verifiable();
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Verifiable();
|
||||
// Don't care if this throws - that's OK
|
||||
try { this.windowManager.CreateWindow(model, false); }
|
||||
catch (Exception) { }
|
||||
|
@ -72,28 +72,16 @@ namespace StyletUnitTests
|
|||
public void CreateWindowThrowsIfViewIsntAWindow()
|
||||
{
|
||||
var model = new object();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model)).Returns(new UIElement());
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(new UIElement());
|
||||
Assert.Throws<ArgumentException>(() => this.windowManager.CreateWindow(model, false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateWindowBindsViewToModel()
|
||||
{
|
||||
var model = new object();
|
||||
var window = new Window();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model)).Returns(window);
|
||||
|
||||
this.windowManager.CreateWindow(model, false);
|
||||
|
||||
this.viewManager.Verify(x => x.BindViewToModel(window, model));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateWindowSetsUpTitleBindingIfViewModelIsIHaveDisplayName()
|
||||
{
|
||||
var model = new Screen();
|
||||
var window = new Window();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||
|
||||
this.windowManager.CreateWindow(model, false);
|
||||
|
||||
|
@ -106,7 +94,7 @@ namespace StyletUnitTests
|
|||
public void CreateWindowActivatesViewModel()
|
||||
{
|
||||
var model = new Mock<IScreen>();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(new Window());
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(new Window());
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
model.Verify(x => x.Activate());
|
||||
}
|
||||
|
@ -116,7 +104,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
window.WindowState = WindowState.Maximized;
|
||||
window.OnStateChanged(EventArgs.Empty);
|
||||
|
@ -128,7 +116,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
window.WindowState = WindowState.Normal;
|
||||
window.OnStateChanged(EventArgs.Empty);
|
||||
|
@ -140,7 +128,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
window.WindowState = WindowState.Minimized;
|
||||
window.OnStateChanged(EventArgs.Empty);
|
||||
|
@ -152,7 +140,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Screen();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||
this.windowManager.CreateWindow(model, false);
|
||||
window.OnClosing(new CancelEventArgs(true));
|
||||
}
|
||||
|
@ -162,7 +150,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
model.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(false));
|
||||
var ea = new CancelEventArgs();
|
||||
|
@ -175,7 +163,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
model.Setup(x => x.CanCloseAsync()).Returns(Task.FromResult(true));
|
||||
var ea = new CancelEventArgs();
|
||||
|
@ -188,7 +176,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
model.Setup(x => x.CanCloseAsync()).Returns(Task.Delay(1).ContinueWith(t => false));
|
||||
var ea = new CancelEventArgs();
|
||||
|
@ -201,7 +189,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
model.Setup(x => x.CanCloseAsync()).Returns(Task.Delay(1).ContinueWith(t => true));
|
||||
var ea = new CancelEventArgs();
|
||||
|
@ -214,7 +202,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
var tcs = new TaskCompletionSource<bool>();
|
||||
model.Setup(x => x.CanCloseAsync()).Returns(tcs.Task);
|
||||
|
@ -234,7 +222,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Screen();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model)).Returns(window);
|
||||
this.windowManager.CreateWindow(model, false);
|
||||
((IChildDelegate)model.Parent).CloseItem(new object());
|
||||
}
|
||||
|
@ -244,7 +232,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
object parent = null;
|
||||
model.SetupSet(x => x.Parent = It.IsAny<object>()).Callback((object x) => parent = x);
|
||||
this.windowManager.CreateWindow(model.Object, false);
|
||||
|
@ -258,7 +246,7 @@ namespace StyletUnitTests
|
|||
{
|
||||
var model = new Mock<IScreen>();
|
||||
var window = new MyWindow();
|
||||
this.viewManager.Setup(x => x.CreateAndSetupViewForModel(model.Object)).Returns(window);
|
||||
this.viewManager.Setup(x => x.CreateAndBindViewForModel(model.Object)).Returns(window);
|
||||
object parent = null;
|
||||
model.SetupSet(x => x.Parent = It.IsAny<object>()).Callback((object x) => parent = x);
|
||||
this.windowManager.CreateWindow(model.Object, true);
|
||||
|
|
Loading…
Reference in New Issue