Visual Studio 2012 - Variable missing from Locals Window - debugging

I have never seen this before and have no idea what it causing it.
When I put a breakpoint at the end of code below, the elapsedSeconds variable is NOT listed in the locals window. If I try to Watch it, the Value = "The name 'elapsedSeconds' does not exist in the current context". How is that possible???
public ActionResult Index()
{
Stopwatch sw = Stopwatch.StartNew();
var userID = WebSecurity.GetUserId(User.Identity.Name);
var model = ModelHelper.GetModel(userID);
long elapsedSeconds = 0;
elapsedSeconds = sw.ElapsedMilliseconds;
return View(model);
}

Select 'Code Optimization' property as "Disabled" in Project property window, in case you want to take a look at the value. It's the compiler optimization process, that renders evaluating that variable unnecessary.

I got this too in a Web project. Neither restarting Visual Studio or any other solution in this thread sovled it.
My solution was to restart IIS. After that I rebuilt the project and started it and got locals to work again.

Rebuilding the solution helped in getting the variable hover feature back.

Related

Automate a reoccuring manual task (generate order number based on name) in Visual Studio

I'm currently working on a EpiServer project where we use the ContentType attribute to set the DisplayName and Order of the blocks. The Order is based on the name of the block. Here's an example:
[ContentType(
DisplayName = "My First Block",
Order = 133536,
GUID = "0f02e38a-a6e2-4333-9bd1-c61cf573d8d3",
Description = "Just an example block.",
GroupName = "Blocks.Content"
)]
public class MyFirstBlock : BaseBlock
{
}
Apparently EpiServer can't sort the blocks alphabetically so we generate the order based on the DisplayName as a work around. A formula was invented to determine the order. One colleague has written a JavaScript function that can be used to generate the order number:
function getEPiOrderNumber(value) {
var alphabeticalIndex = function (character) {
return character.toLowerCase().charCodeAt() - 96;
};
var firstSection = alphabeticalIndex(value[0]);
var secondSection = alphabeticalIndex(value[1]) + 10;
var thirdSection = alphabeticalIndex(value[2]) + 100;
return `${firstSection}${secondSection}${thirdSection}`;
}
This function can be executed in the console of a browser. Better than having to calculate the order by hand, but this requires that I switch to a browser, open the console, paste this code and execute it and finally copy the result and paste it in the model I'm working on.
I figured it would be much more convenient to be able to do generate the order number from within VS. I have been looking into using Visual Studio Extensions but can't really find anything that is to my liking.
The most optimal solution would be to be able to select the (part of the) DisplayName, right click and select a new command from the context menu that will generate the order and paste it at the correct location. Or place it on the clip board so I can easily paste it in the right location myself. A pop-up displaying the order would be fine as well.
Is this even possible?
Another option could be a new command in one of the toolbar menu's, say Tools, that would display a small window where I can enter/ paste the text and to have it generate the order that I can then paste in the code.
I have figured out how to add an Custom Command to the Tools menu and how I could generate the code and display it, but how can I enter the text? Or is it maybe possible to retrieve selected text from the editor window? That would solve my problem as well.
If anyone could point me in the right direction, that would be great!
PS. I'm not too happy with the title of this question so I'm open to suggestions if anyone can think of a title that better describes my question.
You could retrieve selected text from Visual Studio editor window with following code.
DTE dte = (DTE)this.ServiceProvider.GetService(typeof(DTE));
string text = "";
if (dte.ActiveDocument != null)
{
var selection = (TextSelection)dte.ActiveDocument.Selection;
text = selection.Text;
}

SubreportProcessing event handler cannot access my viewmodel due to being on a different thread

I have a WPF application that is utilizing the reporting tools included with Visual Studio 2010. I've had some other problems that I've solved by creating a graph of objects that are all marked as serializable, etc., as mentioned on various other web pages.
The ReportViewer control is contained in a WindowsFormsHost. I'm handling the SubreportProcessing event of the ReportViewer.LocalReport object to provide the data for the sub report.
The object graph that I'm reporting on is generated in my viewmodel, and that viewmodel holds a reference to it. The SubreportProcessing handler is in my code behind of my window (may not be the best place - but I simply want to get the ReportViewer working at this point).
Here's the problem: In my event handler, I'm attempting to get a reference to my viewmodel using the following code:
var vm = DataContext as FailedAssemblyReportViewModel;
When the handler is called, this line throws an InvalidOperationException with the message The calling thread cannot access this object because a different thread owns it.
I didn't realize the handler might be called on a different thread. How can I resolve this?
I attempted some searches, but all I've come up with is in regards to updating the UI from another thread using the Dispatcher, but that won't work in this case...
I solved this problem using something I believe is a hack, by adding the following function:
public object GetDataContext() {
return DataContext;
}
And then replacing the line of code from my question with:
object dc = Dispatcher.Invoke(new Func<object>(GetDataContext), null);
var vm = dc as FailedAssemblyReportViewModel;
However, this seems like a hack, and I might be circumventing some sort of safety check the CLR is doing. Please let me know if this is an incorrect way to accomplish this.
That's a nasty problem you have there.
Why don't you use in the view a content presenter which you bind to a windows form host?
And in the view model you would have a property of type of type WindowsFormsHost. Also,in the view model's constructor you could set the windows form's host Child property with the report viewer.
After that is smooth sailing, you could use your report viewer anywhere in your code. Something like this:
View:
<ContentPresenter Content="{Binding Path=FormHost}"/>
ViewModel:
private ReportViewer report = new ReportViewer();
private WindowsFormsHost host = new WindowsFormsHost();
public WindowsFormsHost FormHost
{
get {return this.host;}
set
{
if(this.host!=value)
{
this.host = value;
OnPropertyChanged("FormHost");
}
}
}
public ViewModel() //constructor
{
this.host.Child = this.report;
}
After that happy coding. Hope it helps.

How to refresh reading pane content in Outlook 2010

We use redemption tools to populate stub-mails with real content. After calling RDOMail.Import(...) on the selected item, we close and reopen the preview (reading) pane in outlook using
m_Explorer.ShowPane(MSOutlook.OlPane.olPreview, false);
m_Explorer.ShowPane(MSOutlook.OlPane.olPreview, true);
This method works well in Outlook 2007.
But in Outlook 2010 programmatical refresh attempts (Close/Open Reading pane, Deselect/Select the updated item) do not work at all. Outlook 2010 still shows the old version.
Does anyone have a hint or a possible solution?
Many thanks in advance.
Did you try just calling Close on the MailItem? This refreshes content if the item is selected for me. Seems an easier solution to what you are suggesting.
Finally, we solved it!
The solution is to
1) Remove the item to update context.RemoveItem(TargetData.EntryID); (We are using some abstractions over RDOMessage, MailItem, RDOFolder and MAPIFolder. But I think, the principle behind is quiet clear.
2) Add the new item (WithComCleanup is from VSTOContrib project)
using (var msg = RDOSession.Resource.GetMessageFromMsgFile(pathToMSG)
.WithComCleanup())
{
msg.Resource.Move(context.RDOFolder);
msg.Resource.Save();
}
3) Attach an ItemAdd handler to RDOFolder or MAPIFolder, note that the items collection has to be declared on class level!
Why ItemAdd? Because neither RDOMail.OnModified nor RDOMail.OnMoved provided a valid EntryID required for MailItem retrieval. We write custom UserAttributes on fetching, and read them in ItemAdd...
//...
m_OwnItems = m_Folder.Items
m_OwnItems.ItemAdd += new MSOutlook.ItemsEvents_ItemAddEventHandler(Items_ItemAdd);
//...
void Items_ItemAdd(object Item)
{
//Outlook 2010: Version 14, only Outlook 2010 supports `ClearSelection` and `AddToSelection`
if (Item is MSOutlook.MailItem && ApplicationController.Instance.ApplicationVersion.Major >= 14)
{
var mail = Item as MSOutlook.MailItem;
//Check that the added item is the one you added with GetMessageFromMsgFile
//...
if (m_Explorer.IsItemSelectableInView(mail))
{
m_Explorer.ClearSelection();
m_Explorer.AddToSelection(mail);
}
}
}
4) It's done! This behavior of Outlook 2010 annoyed us for the whole development time...
Keep in mind that RDOMail.Move returns the new object (just like OOM).
Since you are recreating the message, its creation time will change.

How to programmatically change settings in VS2010 property sheet?

I am looking for a method (macro/plugin/extension) to change values in a specific property sheet (which is loaded into every project in the solution) without having to reload the solution.
Is there a way to access it from a macro or plugin code?
Thanks!
Record a macro when you edit the property sheet and view it's code from the macros IDE. Afterwards you could assign key bindings to it and playback anytime.
This is how I got to work. And you have to add the VCEngine reference with your project.
VCProject project;
Projects projCollection = sol1.Projects;
project = (VCProject)projCollection.Item(1).Object;
VCConfiguration config = project.Configurations.Item("Test Release|Win32");
IVCRulePropertyStorage rule = config.Rules.Item("ConfigurationDirectories") as IVCRulePropertyStorage;
//Setting the Include directories
string rawValue = rule.GetUnevaluatedPropertyValue("IncludePath");
string evaluatedValue = rule.GetEvaluatedPropertyValue("IncludePath");
rule.SetPropertyValue("IncludePath", "Whatever you like to specify here");
//Setting the Executable Directory
rawValue = rule.GetUnevaluatedPropertyValue("ExecutablePath");
rule.SetPropertyValue("ExecutablePath", "Whatever you like to specify here");

IsolatedStorageSettings needs Update?

I'm using IsolatedStorageSettings on WP7 to store an objects list:
List<T>
I need to search an item inside my list and to update some properties of the searched item.
I'm using this code:
List<Article> listArt = null;
IsolatedStorageSettings.ApplicationSettings.TryGetValue("ArticleListStorage", out listArt);
var queryList = (from anItem in listArt where (anItem.Id == _id) select anItem).ToList<Article>();
a = queryList[0] as Article;
//mark Article as read
a.Readed = true;
When I continuously navigate the various page inside the app, I can see the property Readed correctly evalued.
But, when I click on WP7 Start button and reopen my app (without close emulator) I see the property not correctly evalued.
Need I to update my object inside list and so inside Isolated Storage?
Not updated by reference?
I tried also this, ant it doesn't work:
listArt[0].Readed = true;
listArt[0].Favorite = true;
IsolatedStorageSettings.ApplicationSettings["ArticleListStorage"] = listArt;
IsolatedStorageSettings.ApplicationSettings.Save();
What is wrong?
Thank you so much!
You can either explicitly call Save() on the settings or wait for the app to close normally and then they will be saved automatically.
As a general rule I'd suggest always explicitly saving settings once you change them. (Unless you have a very good reason not to.)
What's happening in your situation is that you are pressing the start button which causes your app to tombstone. When you launch a new instance of the app the tombstoned version is destroyed without all the code which normally runs on application close (including auto-saving settings) being executed.
Here's and example of using Save:
var settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains("some-key"))
{
settings.Remove("some-key");
}
settings.Add("some-key", "my-new-value");
settings.Save();
Yes, you've got to save your list again. Think of isolated storage as a file system - you wouldn't expect to be able to load an XDocument from disk, make changes in memory and automatically see those changes reflected on disk, would you? Well, it's the same with isolated storage.

Resources