By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,241 Members | 1,980 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,241 IT Pros & Developers. It's quick & easy.

loading Markup::XamlReader::Load from resource file

P: n/a
Since currently we aren't allowed to have compiled XAML files embedded in C++
apps I'm using Markup::XamlReader::Load to dynamically load XAML files. This
works perfectly fine with external files but I'd like to be able to load a file
specified in a .resx resource.

I've added my .xaml file to the .resx and can load it in using
ResourceManager::GetObject(). The object returned is a System::Array^ which
contains System::Byte objects. The problem is that I can't figure out how to get
a stream from that which I can pass to XamlReader.

I've tried the following-

1. Use ResourceManager::GetStream(). This threw an InvalidOperationException
saying that the resource was not a stream, call GetObject instead.

2. Copy the Array to a IO::MemoryStream byte by byte. For some reason this
mangled the XML enough so that it couldn't be read. This also seems pretty
horribly inefficient.

Any help would be appreciated-

John
Nov 30 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Hi John,
>This works perfectly fine with external files but I'd like to
be able to load a file specified in a .resx resource.
Based on my research, currently there seems not existed a direct way to use
Markup::XamlReader::Load from a XAML resource file. I suggest you can also
consult this issue in our corresponding MSDN forum, you may get more ideas
on this issue there:

Windows Presentation Foundation ("Avalon")
http://forums.microsoft.com/MSDN/Sho...D=119&SiteID=1
Thanks!

Best regards,

Gary Chang
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Dec 1 '06 #2

P: n/a
Hi,

John Dunn wrote:
Since currently we aren't allowed to have compiled XAML files embedded
in C++ apps I'm using Markup::XamlReader::Load to dynamically load XAML
files. This works perfectly fine with external files but I'd like to be
able to load a file specified in a .resx resource.

I've added my .xaml file to the .resx and can load it in using
ResourceManager::GetObject(). The object returned is a System::Array^
which contains System::Byte objects. The problem is that I can't figure
out how to get a stream from that which I can pass to XamlReader.
Are you using 2.0?

If so, try the following method:

Assembly oAssembly = Assembly.GetAssembly( tyResourceType );
Stream stmInput
= oAssembly.GetManifestResourceStream( strPathInResource );

Note that the path in resources starts with the assembly's name, and
uses '.' instead of the usual '\' or '/', so for example if your XAML
file is placed in a folder named "Xaml", the full path is (for example):

GalaSoftLb.MyApplication.Xaml.myxamlfile.xaml

Best way to find out what is the path of your resources is to
Assembly.GetManifestResourceNames in debug mode, and to check all the
resources' names.
http://msdn2.microsoft.com/en-us/lib...urcenames.aspx

HTH,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
Private/Malaysia: http://mypage.bluewin.ch/lbugnion
Support children in Calcutta: http://www.calcutta-espoir.ch
Dec 4 '06 #3

P: n/a
Laurent Bugnion wrote:
Hi,

John Dunn wrote:
>Since currently we aren't allowed to have compiled XAML files embedded
in C++ apps I'm using Markup::XamlReader::Load to dynamically load
XAML files. This works perfectly fine with external files but I'd like
to be able to load a file specified in a .resx resource.

I've added my .xaml file to the .resx and can load it in using
ResourceManager::GetObject(). The object returned is a System::Array^
which contains System::Byte objects. The problem is that I can't
figure out how to get a stream from that which I can pass to XamlReader.

Are you using 2.0?

If so, try the following method:

Assembly oAssembly = Assembly.GetAssembly( tyResourceType );
Stream stmInput
= oAssembly.GetManifestResourceStream( strPathInResource );

Note that the path in resources starts with the assembly's name, and
uses '.' instead of the usual '\' or '/', so for example if your XAML
file is placed in a folder named "Xaml", the full path is (for example):

GalaSoftLb.MyApplication.Xaml.myxamlfile.xaml

Best way to find out what is the path of your resources is to
Assembly.GetManifestResourceNames in debug mode, and to check all the
resources' names.
http://msdn2.microsoft.com/en-us/lib...urcenames.aspx
HTH,
Laurent
Thanks for the reply-

I'm using 3.0. I tried iterating the Resource names - only 1 resource was shown
even though I have 2 files added to my resx file. It returned
'db.test_resource.resources' where db is my app name and test_resources is my
resource file name. I'm not sure where it got the final resources string from. I
also tried iterating GetModules ( only returned db.exe ) and GetFiles ( returned
path_to_exe\db.exe ) without any luck.

The relevant portion of the resx file looks like this

<data name="window_close_button" type="System.Resources.ResXFileRef,
System.Windows.Forms">
<value>res\window_close_button.xaml;System.Strin g, mscorlib,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>

The only other thing that may be an issue is that I'm calling
Assembly::GetExecutingAssembly() to get the Assembly. That seemed to work when I
needed an Assembly to pass into the ResourceManager constructor. If I need to
call GetAssembly I'm not sure what type to pass into that call.

Thanks-

John
Dec 4 '06 #4

P: n/a
Hi,

John Dunn wrote:
Laurent Bugnion wrote:
>Hi,

Are you using 2.0?

If so, try the following method:

Assembly oAssembly = Assembly.GetAssembly( tyResourceType );
Stream stmInput
= oAssembly.GetManifestResourceStream( strPathInResource );

Note that the path in resources starts with the assembly's name, and
uses '.' instead of the usual '\' or '/', so for example if your XAML
file is placed in a folder named "Xaml", the full path is (for example):

GalaSoftLb.MyApplication.Xaml.myxamlfile.xaml

Best way to find out what is the path of your resources is to
Assembly.GetManifestResourceNames in debug mode, and to check all the
resources' names.
http://msdn2.microsoft.com/en-us/lib...urcenames.aspx
HTH,
Laurent

Thanks for the reply-

I'm using 3.0.
Oh, duh *LOL* Answering to a post in the WPF newsgroup, this should be
obvious to me. Sorry. I spend too much time in the ASP.NET and C# NGs ;-)
I tried iterating the Resource names - only 1 resource
was shown even though I have 2 files added to my resx file. It returned
'db.test_resource.resources' where db is my app name and test_resources
is my resource file name. I'm not sure where it got the final resources
string from. I also tried iterating GetModules ( only returned db.exe )
and GetFiles ( returned path_to_exe\db.exe ) without any luck.
I suspect that you add the files to the RESX file the old (1.1) way.

To add a file to resources in the 2.0 (and 3.0) way, you do as follow:

1) Add the XAML file to your project, using "Add existing file". The
file may be in a folder too, that's OK.

2) Select the file, select Properties (F4)

3) Set "Build action" to "Embedded resource"

Voilą. Next time you compile, the file will be added to the DLL without
you having to fiddle with the RESX file. Neat ;-)

After this, it should occur in the Resource names as standalone.
The relevant portion of the resx file looks like this

<data name="window_close_button" type="System.Resources.ResXFileRef,
System.Windows.Forms">
<value>res\window_close_button.xaml;System.Strin g, mscorlib,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
Yes. Use the other way described above, it's easier and will act as
expected.
The only other thing that may be an issue is that I'm calling
Assembly::GetExecutingAssembly() to get the Assembly. That seemed to
work when I needed an Assembly to pass into the ResourceManager
constructor. If I need to call GetAssembly I'm not sure what type to
pass into that call.
GetExecutingAssembly() will return the current assembly, which is
probably fine for that you do. My code is generic, I use it in a Utility
class to extract resources embedded in any assembly, which I identify
using a type present in that assembly.

HTH,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
PhotoAlbum: http://www.galasoft-LB.ch/pictures
Support children in Calcutta: http://www.calcutta-espoir.ch
Dec 4 '06 #5

P: n/a
Laurent Bugnion wrote:
1) Add the XAML file to your project, using "Add existing file". The
file may be in a folder too, that's OK.

2) Select the file, select Properties (F4)

3) Set "Build action" to "Embedded resource"
Step 2 isn't working for me. I add the resource with the 'Add existing file...'
button and the only properties I can set on my resource are (Name), Comment and
FileType. Filename, Persistance and Type are grayed out on any of the files I add.

I tried adding an image and I could then change the Perstance to either 'Link at
compile time' or 'Embedded in Resx'. Trying either of those didn't make the
image show up in GetManifestResourceNames.

I'm guessing that I'm missing an obvious step since this is my first foray into
Resource Assemblies.

John
Dec 4 '06 #6

P: n/a
Hi,

John Dunn wrote:
Laurent Bugnion wrote:
>1) Add the XAML file to your project, using "Add existing file". The
file may be in a folder too, that's OK.

2) Select the file, select Properties (F4)

3) Set "Build action" to "Embedded resource"

Step 2 isn't working for me. I add the resource with the 'Add existing
file...' button and the only properties I can set on my resource are
(Name), Comment and FileType. Filename, Persistance and Type are grayed
out on any of the files I add.
Strange. I just tried it again on a WPF application here, just to be
sure, and it works fine. I created a "Resources" folder, then added a
new ResourceDictionary (MyFile.xaml) in it, and then I can set the Build
action as I described. BTW, I use Visual Studio 2005 professional.

Can you tell me which type of project you created (WPF application?
XBAP? other?) and which version of the .NET Framework 3.0 you're using?
Oh, and also, which version of Visual Studio are you using?

Also, if you want, can you send me the project files zipped? (my email
address is genuine). Really curious why it doesn't work.
I tried adding an image and I could then change the Perstance to either
'Link at compile time' or 'Embedded in Resx'. Trying either of those
didn't make the image show up in GetManifestResourceNames.

I'm guessing that I'm missing an obvious step since this is my first
foray into Resource Assemblies.

John
HTH,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
PhotoAlbum: http://www.galasoft-LB.ch/pictures
Support children in Calcutta: http://www.calcutta-espoir.ch
Dec 4 '06 #7

P: n/a
Laurent Bugnion wrote:
Can you tell me which type of project you created (WPF application?
XBAP? other?) and which version of the .NET Framework 3.0 you're using?
Oh, and also, which version of Visual Studio are you using?
I'm guessing the problem is that I'm writing a C++/CLI application. It doesn't
look like I have access to the same set of resource properties that C# apps
have. I'm using VS2005 so I'll send you a zipped project but I'm probably out of
luck.

I did a quick WPF project and I do get the Embedded Resource option.

John
Dec 4 '06 #8

P: n/a
Hi John,

John Dunn wrote:
Laurent Bugnion wrote:
>Can you tell me which type of project you created (WPF application?
XBAP? other?) and which version of the .NET Framework 3.0 you're
using? Oh, and also, which version of Visual Studio are you using?

I'm guessing the problem is that I'm writing a C++/CLI application. It
doesn't look like I have access to the same set of resource properties
that C# apps have. I'm using VS2005 so I'll send you a zipped project
but I'm probably out of luck.

I did a quick WPF project and I do get the Embedded Resource option.

John
I got your files. Yes, I guess that you cannot embed files in an
assembly the same way in C++ as you do in C#. I wasn't aware of the fact
(never tried managed C++, my experiences with C++ were in the embedded
world only, and a few years ago ;-)

I think that your idea to create a C# assembly for resources is a good
one. I hope that'll work better.

Greetings,
Laurent
--
Laurent Bugnion, GalaSoft
Software engineering: http://www.galasoft-LB.ch
PhotoAlbum: http://www.galasoft-LB.ch/pictures
Support children in Calcutta: http://www.calcutta-espoir.ch
Dec 5 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.