How to free WPF resources after they are no longer being used - wpf

I use a default image as a user avatar the first time my application is loaded. After that, the user can change their avatar. The problem is that after using a new avatar, the user cannot delete the old avatar. They get the error message: "file access denied". That means my application is still using the old image somewhere, but I don't know where.
My question is: How do I free the WPF resource after using it? I have looked around with Google, but found nothing.
Please help me!
Thanks.

You usually have to call Dispose() on class instances after use to free resources. Even better is to use the using statement that implicitly calls Dispose() like this:
using (FileStream fsSource = new FileStream(pathSource, FileMode.Open, FileAccess.Read))
{
// Load file content
}

Related

How to handle Solutions, Projects and their contents in a VisualStudio extension

In short:
I'm new to VisualStudio Extensibility and my goal is to create an extension with a ToolWindow (which already works) showing different views for each context of a VisualStudio solution, i. e. a view for the solution, a view for a project etc.. The window should be opened by clicking on a context menu entry in the context menus of the Solution Explorer, Class View, Object Browser and (ideally) any other window showing contents like projects, namespaces, classes etc..
After searching I found a lot of information, but for some points I couldn't find very helpful information. How do I ...
... create a context menu item for the VisualStudio views?
... get the currently open solution as an instance in code?
... get the projects of the solution and their contens as instances in code?
... add/remove items to/from a solution/project/class/... in code?
... react to selection changes in the Solution Explorer?
What I've done, so far:
I read the docs for Starting to Develop Visual Studio Extensions and downloaded the VSSDK-Extensibility-Samples. Especially the WPF_Toolwindow example was interesting for my purposes, so I built and ran it, which was successful, so far. Another interesting sample would have been the WPFDesigner_XML, but it always throws a NullReferenceException, so I decided to stick with the former ToolWindow, which is completely fine, for now.
Furtermore, I tried to understand the example by having a close look at each file in the project, running it in the debugger and analyzing what happened. I'm confident I understood it, but am also open for corrections of my possibly misguided thoughts following.
Now, I have created a new project, based on the WPF_Toolwindow sample, renamed and adapted to my needs (basically, I created new GUIDs, renamed the namespaces and removed things I won't use). This extension still works in the debugger. I even uninstalled everything from the experimental instance and debugged the extension from scratch.
What I try to achieve:
Have the ToolWindow load a specific view/viewmodel, when the selection changes in the Solution Explorer (or any other VisualStudio view). Alternatively, there should be a context menu item for every node's context menu in the Solution Explorer tree (or any other VisualStudio view).
Get the currently open solution, the containing projects and basically everything from the Solution Explorer's content as instances processable in my viewmodel. I need to properly add/remove
classes/structs/enums to/from
a folder in a project
a namespace
properties/fields to/from a class/struct
Generate code based on information of the solution and add the file properly to a project.
Does anyone know of examples for something like this or can anyone give me some hints, where I can find further information? Any help would be appreciated. Thanks in advance.
(1) The items already have a context menu and I want to add a new command to this menu.
if you want to add a sub menu to the context menu, the following link provide a complete sample
https://github.com/visualstudioextensibility/VSX-Samples/tree/master/CommandSubmenu
(3) Yes, basically adding a file to a project without manually manipulating the project file would be nice.
You can add the file to project via Project.ProjectItems.AddFromFile, and the following provide a sample for your reference.
https://www.mztools.com/Articles/2014/MZ2014009.aspx
Update:
I select a project and a similar event is fired. Are there such events I can subscribe to?
You could use IVsMonitorSelection to implement. here is the code which retrieve related project path for your reference.
IntPtr hierarchyPointer, selectionContainerPointer;
Object selectedObject = null;
IVsMultiItemSelect multiItemSelect;
uint projectItemId;
IVsMonitorSelection monitorSelection =
(IVsMonitorSelection)Package.GetGlobalService(
typeof(SVsShellMonitorSelection));
monitorSelection.GetCurrentSelection(out hierarchyPointer,
out projectItemId,
out multiItemSelect,
out selectionContainerPointer);
IVsHierarchy selectedHierarchy = Marshal.GetTypedObjectForIUnknown(
hierarchyPointer,
typeof(IVsHierarchy)) as IVsHierarchy;
if (selectedHierarchy != null)
{
ErrorHandler.ThrowOnFailure(selectedHierarchy.GetProperty(
projectItemId,
(int)__VSHPROPID.VSHPROPID_ExtObject,
out selectedObject));
}
Project selectedProject = selectedObject as Project;
string projectPath = selectedProject.FullName;
For more information about the usage, please refer to:
https://www.mztools.com/articles/2007/mz2007024.aspx

Codenameone new GUI Builder null pointer when trying to assign image to button

When using the new GUI Builder (CN1 plugin v3.6.0) I can attach an image from my res file to a Button and it appears in the preview nicely
but when I try to run the code in the Simulator I get a NullPointerException on the line
gui_ordersButton.setIcon(resourceObjectInstance.getImage("Orders.png"));
As this is in the magic "do not edit below this line" block how can I fix this?
Many thanks.
Two elements can throw a null pointer from this exact line:
gui_ordersButton.setIcon(resourceObjectInstance.getImage("Orders.png"));
gui_ordersButton or resourceObjectInstance. If the image isn't available in the resources the null pointer will come from the setIcon method.
I'm guessing resourceObjectInstance is null because you changed something about the way resources are loaded in the default project or you used the constructor of the form that passes null as the resources object.

FatalExecutionEngineError in RichTextBox

Sometimes, just sometime, I get FatalExecutionEngineError while trying to get text position from mouse position in RichTextBox. And the second problem is I can't handle FatalExecutionEngineError and it crashes the app.
// e.MouseDevice.GetPosition(XAMLRichBox) is not null
var tp = myRichBox.GetPositionFromPoint(e.MouseDevice.GetPosition(XAMLRichBox), true);
I've encountered the similar problem when working with RichTextFormat and probably my experience may help you too.
I've encountered the abovementioned exception when user was calling Undo action in richtextedit control. The exception was thrown on undo if there are particular actions has been done previously that included the insert into CaretPosition the content of the separately created FlowDocument:
Document.ContentStart.InsertParagraphBreak();
RichTextBox.InsertDocument(Document, RichTextBox.CaretPosition);
My solution was to envelope the above action in BeginChange()/EndChange() (that was perfectly suited the requirements):
RichTextBox.BeginChange();
try
{
Document.ContentStart.InsertParagraphBreak();
RichTextBox.InsertDocument(Document, RichTextBox.CaretPosition);
}
finally
{
RichTextBox.EndChange();
}
I guess this might give you idea to solve your problem

Sharing Linq to SQL DataContext between WP7.1 and WPF apps?

I have built a WP7.1 application that uses a local database. I used sqlmetal to generate the data context as per this article. http://blogs.microsoft.co.il/blogs/alex_golesh/archive/2011/05/24/windows-phone-mango-what-s-new-local-database-part-1-of-8.aspx
This works as expected using this in the ViewModel.
context = new BirdsnBflysDC("DataSource='isostore:BirdsnBflys.sdf'");`
I am now attempting to "share" the Model and ViewModel code with a WPF application. Initially I added the appropriate files as a link to the WPF project. Creating an instance of the context didn't work so as a test I have added just the data context code to a WPF project and attempt to create an instance of the context in the Loaded event handler as follows.
BirdsnBflysDC context = new BirdsnBflysDC("DataSource='C:\BirdsnBflys.sdf'");
DataContext = context;
The code actually has the complete path to the database. When I step through this in the debugger the context initialization in the data context quits running as if there was an exception, the second line of code above is never reached and the WPF window is shown as if things completed correctly.
I've tried several variation in the DataSource string including "|DataDirectory|\\BirdsnBflys.sdf" all with the same result.
Any suggestions as where to go with this? How to figure out what isn't working correctly?
Thanks,
Dave
The problem is that what is expected in the connection string is different for the two environments.
WP7 works with this.
context = new BirdsnBflysDC("DataSource='isostore:BirdsnBflys.sdf'");
WPF works with this.
context = new BirdsnBflysDC("|DataDirectory|\BirdsnBflys.sdf");
If you give WPF a file name that isn't there you get no error information, the instantiation of the data context fails quietly and any additional code does not get executed.
Dave
Did you remove the 2 methods from the generated cs file? I mean the methods unsupported by mango.
public ExternalDB(System.Data.IDbConnection connection) :
base(connection, mappingSource)
{
OnCreated();
}
public ExternalDB(System.Data.IDbConnection connection,
System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
I am not sure about this, but they might be needed for wpf.
Hope this helps.

Silverlight Image Loading

I'm a beginner just beginning to work with Silverlight with a very basic question. I want to display a .png image. I have already done it in the page.xaml file but I would like to do it in code (C#) so that I can add and remove images while my program is running. I have seen some code in which you add an image to the Children of a Canvas, but when I do this no images are ever displayed. Could someone provide some code and where to put it? Here is what I've been working with. There are no exceptions, but no image appears.
page.myCanvas.Children.Add(LoadImage("Image/MrBlue"));
public Image LoadImage(string resource)
{
Image img = new Image();
Uri uri = new Uri(resource, UriKind.Relative);
ImageSource imgSrc = new System.Windows.Media.Imaging.BitmapImage(uri);
img.SetValue(Image.SourceProperty, imgSrc);
return img;
}
The image is set to "Resource" and "Do not Copy."
Debugging Silverlight can be a pain, although it's quite possible to set up in VS2008 (which you might already have done. If you haven't feel free to ask...) and that can catch some of the 'simple' errors like having the wrong Uri for the image you want. Your code looks fine to me, although what I'm using is slightly different. If you want an example from a working app, the function I use for loading images is:
public void ShowPicture(Uri location)
{
Image pic = new Image();
pic.Source = new BitmapImage(location);
Grid.SetColumn(pic, 1);
Grid.SetRow(pic, 1);
LayoutRoot.Children.Add(pic);
}
Note that I have a using statement that includes System.Windows.Media.Imaging.
Even without full debugging, a utility like fiddler that shows the http requests might help track down bad Uris in code, which is all I can think of that might be wrong here. Hope it helps.
I tested your code and it works fine for me, so as Raumornie already hinted, it would seem to most likely be an issue with the path to the image. As per your code, is the image file located in a folder called Image in your Silverlight project and just named MrBlue? On a quick look, it seems to be missing the .png, or?
Good luck!

Resources