Bug 31811 - Setting the existing ViewController for the storyboard ignores it and creates a new ViewController file in Root directory
Summary: Setting the existing ViewController for the storyboard ignores it and creates...
Alias: None
Product: Visual Studio Extensions
Classification: Xamarin
Component: iOS ()
Version: 3.11 (C5)
Hardware: PC Mac OS
: High critical
Target Milestone: 4.0.0 (C6)
Assignee: Prashant Cholachagudda
Depends on:
Reported: 2015-07-10 02:20 UTC by Prashant Cholachagudda
Modified: 2015-11-10 03:11 UTC (History)
11 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Prashant Cholachagudda 2015-07-10 02:20:39 UTC
Given we have a Storyboard file in "Project\Controllers\MyCodeControllers\MyStoryboard.storyboard"

When I click one of these view controllers in the Designer in Visual Studio, I choose a class for the View Controller in Properties->Widget->Identity->Class: "MyScannerViewController.cs". This class and its associated ".designer.cs" file appears in the "Project\" folder. 
I've tried various methods of moving these classes to "Project\Controllers\MyCodeControllers\", where they should be for reasons of project structure. But I can't seem to move it there; Xamarin appears to create a new, empty view controller at "Project\" when I do.

# Expected result:
The storyboard file should not create a new empty view controller, but use the existing view controller.

Version information: Xamarin 3.11.666.0, Xamarin.iOS
Comment 1 Geir Smestad 2015-07-10 03:16:38 UTC
As an alternate or partial fix to this issue, it would be nice if the Designer created the View Controller (when a class name is entered in the "Class" text field) in the directory of the current Storyboard, and not in the root folder of the current project.
Comment 3 Alan McGovern 2015-07-31 12:03:02 UTC
If you can reproduce this problem can you include all the log files?
Comment 4 Geir Smestad 2015-08-06 07:14:27 UTC
I am unable to reproduce this problem with the latest version of Xamarin. 

Adding a new ViewController class to Project\Controllers\MyCodeControllers and entering its name in the "Class" parameter of a View Controller in the storyboard now produces the expected behavior. (Expected behavior: All the named UIView elements of the View Controller in the storyboard are automatically added to the .designer.cs file of the newly-created ViewController.cs file, and are hence accessible in ViewController.cs). The issue described above (an empty view controller .cs file with the same name as the manually-added one is added to the root directory of the project) does NOT occur.

However, there is still some wonky behavior that's related to the same use case. I have described one such scenario below (Note: This is in Visual Studio):

1. Create project
2. Create folder "SecondStoryboardFolder"
3. Add new iPhone Storyboard View Controller (and associated storyboard) to this folder
4. Open Second Storyboard and add a second view controller

5. Select the second view controller and set its "Class" parameter to SecondStoryboardViewController. The file "SecondStoryboardViewController.cs" and designer file are created in the *root* folder of the project (unexpected behavior), not in SecondStoryboardFolder.
6. Add a button to the second view controller. Give it a name, e.g. "FirstButton". You can now access the FirstButton property in SecondStoryboardViewController.cs, as expected.
7. Move SecondStoryboardViewController.cs to SecondStoryboardFolder by clicking and dragging.
8. Add a button to the second view controller. Give it a name, e.g. "SecondButton". You can *NOT* access the SecondButton property in SecondStoryboardViewController.cs, as it does not appear in SecondStorybaordViewController.designer.cs (unexpected behavior).

9. If compiling the project and segueing to SecondStoryboardViewController, a runtime exception is thrown: "Foundation.MonoTouchException: Objective-C exception thrown.  Name: NSUnknownKeyException Reason: [<SecondStoryboardViewController 0x14cd1ce60> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key SecondButton."

When I did this on one occasion, SecondButton was automatically added to SecondStoryboardViewController.designer.cs after a restart of Visual Studio (assuming that I remember correctly).

Points 1-9 are demonstrated in the linked example project.

Comment 5 Geir Smestad 2015-08-06 07:20:15 UTC
Visual Studio build log for the project above:

Xamarin log output while creating the project above:
Comment 6 Alan McGovern 2015-08-21 10:31:51 UTC
In Visual Studio and Xamarin Studio we rely on an the type system being up to date. If it is not, we will incorrectly generate code like this bug describes.

As this issue can only be reproduced in VS, it looks like VS is not correctly updating it's NRefactory typesystem when files are moved/renamed. Reassigning to the VS component so they can investigate this and apply whatever tweaks they need to keep the type system in sync with the project.
Comment 7 Enzo Heredia 2015-08-25 14:20:48 UTC
reproducible against
Comment 8 xamarin-release-manager 2015-08-27 16:06:14 UTC
Fixed in version (master)

Author: Adrian Alonso
Commit: 93ad21dec0ca84826116cc993e0b0b454cae2d9b (xamarin/XamarinVS)
Comment 9 Alan McGovern 2015-08-27 17:36:13 UTC
My understanding of this bug is:

If a custom class is created and the source is added to the project and that source is moved to a different location in the project, the designer will re-create the files in the original location.

The commit you landed only changes the default location where the files are created, but does not address the actual bug.
Comment 10 Adrian Alonso 2015-08-27 20:04:33 UTC
Alan: For me it seems that the behavior you're mentioning is a side effect of not being able to create the initial ViewController in the folder where the storyboard is. Anyway I will review the scenario you're describing and see what we can do from our side.

I'm assuming that you're not detecting it and calling the IDE service when the storyboard is moved. Not sure if it should be a different bug.

@nzo: what do you think?
Comment 11 Alan McGovern 2015-08-27 20:56:19 UTC
The location of the physical file is irrelevant to us. We don't store or track it. We query the type system for that information whenever we need it. If we have incorrect information and regenerate files in the wrong place it's because the type system is not up to date. If the type system is stale then literally everything to do with code gen will act in strange and unpredictable ways
Comment 12 Alan McGovern 2015-08-28 14:37:09 UTC
I looked into it. I forgot that we had to create the ICompilation in VS instead of VS providing one to use like XS does.

The problem we have is that when moving files in the project, none of these 3 methods is invoked: https://github.com/xamarin/XamarinVS/blob/master/src/Core/VisualStudio.IOS/Designer/VisualStudioIdeServiceProvider.cs#L114-L116

As such, we don't know the move happened. What events can we use?
Comment 13 Daniel Cazzulino 2015-08-28 15:48:12 UTC
The events accessors need to be persisted for the lifetime of the VisualStudioIdeServiceProvider or otherwise they will be GC'ed and the event handlers never get called. 

Please store them in a field: 

> var events = (EnvDTE80.Events2)project.DTE.Events;


> this.events = (EnvDTE80.Events2)project.DTE.Events;
Comment 14 xamarin-release-manager 2015-08-28 15:51:47 UTC
Fixed in version (master)

Author: Alan McGovern
Commit: a6260ce2d3e410193735a45fd31c74189ead35c7 (xamarin/XamarinVS)
Comment 15 Daniel Cazzulino 2015-08-28 15:56:31 UTC
Adrian is taking care of the events fixes so they get properly called.

Comment 16 Enzo Heredia 2015-08-31 15:17:59 UTC
Prashant Can you validate? build
Comment 17 Udham Singh 2015-11-10 03:11:30 UTC
I have checked this issue with latest builds of Cycle6 and observed that setting a existing ViewController for the storyboard does not create a new ViewController file in project root directory. 

Screencast : http://www.screencast.com/t/HJZiNADMpFj

I have also checked the steps (1-9) provided in comment 4 and observed the same behavior mentioned in comment 4.

Screencast : http://www.screencast.com/t/iZMLfjfqpAu

Environment Info : https://gist.github.com/Udham1/36627d812b165855dfdf

@Prashant : Could you please check this issue at your end?