Windows Vista Forums

loading Markup::XamlReader::Load from resource file
  1. #1


    John Dunn Guest

    loading Markup::XamlReader::Load from resource file

    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

      My System SpecsSystem Spec

  2. #2


    Laurent Bugnion Guest

    Re: loading Markup::XamlReader::Load from resource file

    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

      My System SpecsSystem Spec

  3. #3


    John Dunn Guest

    Re: loading Markup::XamlReader::Load from resource file

    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.String, 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

      My System SpecsSystem Spec

  4. #4


    Laurent Bugnion Guest

    Re: loading Markup::XamlReader::Load from resource file

    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.String, 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

      My System SpecsSystem Spec

  5. #5


    John Dunn Guest

    Re: loading Markup::XamlReader::Load from resource file

    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

      My System SpecsSystem Spec

  6. #6


    Laurent Bugnion Guest

    Re: loading Markup::XamlReader::Load from resource file

    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

      My System SpecsSystem Spec

  7. #7


    John Dunn Guest

    Re: loading Markup::XamlReader::Load from resource file

    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

      My System SpecsSystem Spec

  8. #8


    Laurent Bugnion Guest

    Re: loading Markup::XamlReader::Load from resource file

    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

      My System SpecsSystem Spec

loading Markup::XamlReader::Load from resource file problems?

Similar Threads
Thread Thread Starter Forum Replies Last Post
ContextMenu problem after XamlReader.Load() aagranov2007 Avalon 0 19 Nov 2008
Cannot load a dynamic resource in code using a ComponentResourceKey ThoraD Avalon 1 16 Oct 2008
Failed to load resource DLL KiwiNth Vista General 2 04 Aug 2007
Loading Menu and Toolbar Items From a Resource File (Page?) in WPF Bree Avalon 2 28 Nov 2006
RE: Loading Menu and Toolbar Items From a Resource File(Page?) in WPF<1163454875.783518.140940@m73g2000cwd.googlegroups.com> John Vanderburg Avalon 0 21 Nov 2006