3

EDIT:

New Information, just managed to get a logger working (I honestly had no idea cm had one!) and i'm given this message when attempting to use TryClose().

TryClose requires a parent IConductor or a view with a Close method or IsOpen property

I have been stuck on this for a number of days now, and research has turned up zero, I tried posting a question previously about this issue but it received no answers so i assume I didn't word it correctly.

I have a view and viewmodel ContentView/Model which has the following code in them:

ContentView:

<MenuItem Header="New Project" x:Name="OpenProject" cal:Message.Attach="[Event Click] = [Action NewProject()]"/>

ContentViewModel:

public void NewProject()
    {
        NewProjectViewModel viewModel = new NewProjectViewModel(_projectManager);
        _windowManager.ShowWindow(viewModel);
        //If the result is true, we have a new project, otherwise they cancelled the window.
        if (viewModel.Result)
        {
            Project newP = new Project(0, viewModel.ProjectNo, viewModel.ProjectName, 0, 0);
            _projectManager.Insert(newP);
        }
    }

and the viewmodel NewProjectViewModel has the following:

 public void Create()
    {
        this.Result = true;
        TryClose(true);
    }

which is called in the same was as previously using an message.attach on the OK button of the dialog.

However the issue is that TryClose() always fails to close the dialog, and as i don't have the source of caliburn.micro i can't debug inside TryClose() however doing (GetView() As Window).Close() also fails because GetView() always returns null.

I'm at a complete loss as to how i can close this dialog, so any help or suggestions would be greatly appreciated.

EDIT: Since i seem to be getting no answers on this, where as previous questions do, I'll assume i have information missing. In an attempt to understand the issue i think it may have something to with using the view first approach.

In the NewProjectView i have the following:

             xmlns:cal="http://www.caliburnproject.org"
         cal:Bind.Model="ShippingClient.ViewModels.NewProjectViewModel"

This is used to bind the viewmodel rather than the automatic way that is usually used, perhaps this is why GetView() returns null?

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Ben
  • 1,291
  • 2
  • 15
  • 36
  • If you bind using `Bind.Model` it should still wire up all the usual gubbins - could it be that you are calling `GetView` too early (usually best to override `OnViewAttached` before you `GetView`). Worst case scenario, just download the CM source from the codeplex site and add a ref to your project so you can debug. You could also just copy the `WindowManager` code from the CM source and rename it and supply your own `IWindowManager` to CM - this way you can debug just that bit of the CM source – Charleh Aug 14 '13 at 13:48
  • Thanks for the reply, I'm pretty sure its not being called too soon, as i did try overriding AttachView using the code from nemesv in http://stackoverflow.com/questions/10090584/how-to-close-dialog-window-from-viewmodel-caliburnwpf, however debugging that always showed ViewAttached as null. I will give you second suggestion of overriding the default WindowManager with the same code and see what i can find out. – Ben Aug 14 '13 at 14:04
  • Ok with the new information it looks like you are having some problems with bindings - CM is looking for the view to attempt to call `Close` on and can't find it. What implementation of `Window` are you using for your popups? Is it just standard WPF window? – Charleh Aug 14 '13 at 15:41
  • I'm using a WPF UserControl, that is being displayed with the cm WindowManagers ShowDialog, my understand is that it wraps a window around the usercontrol, but i wouldn't like to swear on that. – Ben Aug 14 '13 at 16:23
  • It should do, unless your UC inherits `Window` already so you should be good. I'd check the log for any binding issues - also come to think of it try using `cal:View.Model="{Your binding}"` on your view – Charleh Aug 14 '13 at 16:25
  • It doesn't inherit window, and there are no log issues to do with binding, also did you mean cal:Bind.Model="MyModel" ? if so that is already added to the view, however if you did mean cal:view.model then i'll check that at work tomorrow, Just to make sure i'm not being stupid.. do i need to implement the close function on the view myself..? – Ben Aug 14 '13 at 17:29
  • You shouldn't need to as like you said, it should wrap your control in a window unless it already derives from window - and to be honest both situations would satisfy the criteria for `TryClose`. Try `view.model` – Charleh Aug 14 '13 at 17:36
  • Well i tried using view.model and it had no effect, perhaps i should just attempt to create a conductor for this dialog – Ben Aug 15 '13 at 09:24
  • Not sure why any of this wouldn't work - can you post a small example project reproducing the issue? – Charleh Aug 15 '13 at 10:17
  • I'll give it a shot, knowing my luck a new example will actually work haha, ill get back to you when i've got one. – Ben Aug 15 '13 at 10:23
  • Ok, this is pretty accurate for the setup of our views and viewmodels, and the same way im opening the dialog, it has the same issue. https://www.dropbox.com/s/32a1h88smhmxiw8/TryCloseIssueExample.zip – Ben Aug 15 '13 at 10:57
  • Ok having a look now, gotta give my VS about 15 minutes to open though.... :P – Charleh Aug 15 '13 at 11:06
  • 1
    Figured it out - just a schoolboy error that for some reason I didn't see before! Check my answer – Charleh Aug 15 '13 at 11:26

1 Answers1

4

You are going to absolutely kick yourself:

Remove the cal:Bind.Model and cal:View.Model bindings...

If you are working ViewModel-First (i.e. you are creating a viewmodel and showing it using WindowManager or in a conductor) all the binding stuff that glues the viewmodel to the view is done for you by CM.

In this case you shouldn't use any View-First bindings. What you are essentially doing is newing up another instance of your VM and binding that to your view... so you have two viewmodels in the background, one wired up nicely but not bound any more, and a non-wired up instance which is bound to your view but doesn't know about the conductor.

Just remove any bindings to the viewmodel in your view and it will all work!

Charleh
  • 13,749
  • 3
  • 37
  • 57
  • Oh dear, that is a pretty big oversight by myself there! I can't recall why now, but in the past i've used view first and i've been adding that line on autopilot ever since!. Works like a charm thank you SO much! – Ben Aug 15 '13 at 11:31
  • If I can't use cal:Bind.Model or cal:View.Model, how are you even doing it though? I am having the exact same issue, how can I display my viewModel in a ContentControl without using cal:View.Model? – Joe May 31 '16 at 12:20
  • @joe you shouldn't use them for view model first scenarios, could you open another question on SO with your issue? – Charleh May 31 '16 at 19:17
  • @Charleh, Sensible idea. I have opened a question here: http://stackoverflow.com/questions/37563419/caliburn-micro-how-to-use-contentcontrol-or-display-sub-viewmodel-using-vie – Joe Jun 01 '16 at 08:34