Serializing WPF FlowDocuments to/from PackagePart (including images, etc.) - wpf

I want to be able to store multiple FlowDocuments within a single package, including images, etc. within each document. However, none of the methods I've seen for saving (and loading) Xaml FlowDocuments seem capable of this.
TextRange.Save with DataFormats.Xaml strips images and other embedded content
TextRange.Save with DataFormats.XamlPackage creates a whole new package, rather than allowing me to treat the document and included images as parts within the package I'd be storing it in
XamlWriter looks like it could be good for this, but I can't figure out how to find all the embedded objects for putting in their own parts (although I certainly know how to handle them once I've found them). On the other end, I haven't a clue how to make everything load properly later on.
It's pretty annoying that there's no one-stop way of serializing a FlowDocument and its images, etc. to a PackagePart. If anyone's figured out a good way of doing this, how'd you pull it off?
UPDATE 2011-07-03 00:22: Using XamlWriter and some extra code from this question I've been able to build a happy little OPC-compliant package which can hold multiple FlowDocuments including their images, as PackageParts. However, going the other way (from PackagePart to FlowDocument) is failing, because no matter how I try to load the document, I get XamlParseExceptions telling me that
'Initialization of 'System.Windows.Media.Imaging.BitmapImage' threw an exception.'
So, the question now becomes, how do I manhandle XamlReader.Load and/or my part's stream in order to get the related images loaded properly?

Figured it out. The solution is to manually process the Xaml document before handing it over to XamlReader. Images (and other elements stored as their own PackageParts) need to have the BitmapImage.UriSource property set to include the package Uri (for example, "./Image1.png" in /Content/Document.xaml to "pack://file:,,,C:,Projects,Package.pak/Content/Image1.png").
Two caveats, however:
There's an issue with PackUriHelper.Create(Uri,Uri) however. Instead of using
PackUriHelper.Create(packUri, part.Uri))
you have to use
new Uri(packUri.ToString() + value)
where value is part.Uri with the initial / removed. If you don't do this, instead of getting a proper Uri like above, you get one with an additional comma after the package file name, which confuses and annoys XamlReader.
You need to use FileShare.Read when opening the package, as XamlReader will try and open it itself. By default, Package.Open locks out anyone else trying to open the package, and XamlReader.Load will throw a WebException if it can't get into the package itself.

Related

Looping through materials and meshes (and animations) in a gltf file and importing into three js

I'm sure this has probably been asked before, but I'm fairly new to threejs (and React Fiber), so part of my problem here is not really knowing how to phrase what I need..
I know what I want to do must be possible, because it is possible to drag and drop any gltf file here: https://gltf-viewer.donmccurdy.com/ and see it rendered correctly.
So, what I want to do, is create a loop which will traverse all parts (nodes?) of a gltf model with/without animations (such as this one) and output it as part of a webpage.
Currently, I find myself tediously trying to add a <mesh> for each and every part of a model, and I know there must be an easier way.
I have found the source-code for the viewer here, but as mentioned, I'm still quite new to this library, so any help (or link to a similar question), would be appreciated.

How to get all the AutomationIDs of a WPF application in a file?

In automation of a WPF application (using UI Automation; VSTS 2010), we were adding all the Automation IDs in a Resource File manually and then access it one by one. Considering the application can expand any time, manually adding these IDs can become tedious.
So, is there any tool available which can create this for us? i.e. Get all the ids in a hierarchical format and store it in a file (xml or csv), and then we could parse it whenever required.
I was hoping for a tool like UISpy, which not only can spy all the elements but also export the same.
Do such tools exist? Or is there any alternate approach?
Any valuable feedback is highly appreciated.
Thanks!
I do like this:
public static class AutomationIds
{
public static readonly string MyDataGridId= Create();
private static string Create([CallerMemberName] string name = null)
{
return name;
}
}
<DataGrid AutomationProperties.AutomationId="{x:Static local:AutomationIds.MyDataGridId}"
... />
Then in tests
var dataGrid = window.Get<ListView>(AutomationIds.MyDataGridId);
Assign the automation IDs directly in XAML, then parse XAML files since they are XML after all...
Let's see...
First, I think that your data is not hierarchical - just because a control can be dynamically assigned to be a child of another.
If we change the problem to a subset: "how can we get a hierarchical view of the controls at a time t?" then we can answer this with MS UIA, and say, using a simple RawViewWalker (just a simple breadth-first search on the walker, starting from your main window will do - of course while the application is running so that UIA can reach and query it).
But this subset will not satisfy your initial question, because you'll probably see a portion of your whole ui collection (since some will be hidden / not activated yet at time t).
So it becomes very hard to use a UIA based tool (such as uispy) because then you'll have to set the application view to different states to reach all the controls in your application at different times t1, t2...
I would suggest parsing all your xmls at the same time and build a complete tree of the application's "static" control map, which I believe would be closest to what you're asking for.
Given that this is an old question, I doubt it matters anymore, but just wanted to make the distinctions here.

XPathNavigator in Silverlight

I have a code library that makes heavy use of XPathNavigator to parse some specific xml document. The xml document is cross-referenced, meaning that an element can reference another which has not yet been encountered during parsing:
<ElementA ...>
<DependentElementX id="1234">
</ElementA>
<ElementX id="1234" .../>
The document doesn't really look like this, but the point is that 1) there is an xml schema that enforces the overall document structure, 2) elements inside the document can reference each other using some IDs, and 3) there is quite a few such cross references between different elements in the document.
The document is parsed in two phases. In the first pass I walk through the document
XPathDocument doc = ...;
XPathNavigator nav = doc.CreateNavigator();
nav.MoveToRoot();
nav.MoveToFirstChild()...
and occasionally 'bookmark' the current position (element) in the document using XPathNavigator.Clone() method. This gives me a lightweight instance of an XPathNavigator which I can store somewhere and use later to jump back to a particular place (element) in my document.
Once I have enough information collected in the first pass (for example, I have made sure there is indeed an ElementX with an id='1234'), I jump back to saved bookmarks (using those saved XPathNavigators) and complete the parsing.
Well, now I'm about to use this library in Silverlight 3.0 and to my horror the XPathNavigator is not in the System.Xml assembly.
Questions:
1) Am I missing something obvious (i.e. XPathNavigator does exist in some shape or form, for example in a toolkit or a freeware library)?
2) If I do have to make modifications in the code, what would be the best way to go? Ideally, I would like to make minimal changes, not to rewrite 80% of the code just to be able to use something like XLinq.
To resume, in case I have to give up XPathNavigator, all I need is a way to bookmark places in my document and to get back to them so that I can continue to iterate from where I left off.
Thanks in advance for any help/ideas.
You are not missing something obvious, there is no implementation of XPathNavigator or XPathDocument in the Silverlight versions of the libraries.
The "best way to go" is highly subjective and would really depend on how many lines of code are really depending on XPathNavigator. However I see a couple of choices.
Go ahead and re-write the code using XDocument, XElement etc from the System.Xml.Linq namepsace. This may not be as bad a choice as you might think.
Wrap Xml-to-Linq objects in your own implementation of those properties and methods of the XPathNavigator that you are actually using. It shouldn't be too hard re-create most the features of the XPathNavigator against the Xml-to-Linq objects. You can then run your existing code against your own XPathNavigator.
XPath (xdoc.XPathSelectElements) is available in Silverlight 4: here's an online test tool.
There are tons of ways:
How to deal with XML in C#
You can still use Linq to XML just minus the linq syntax and use the Linq Extension methods.

Read MP3 Tags with Silverlight

Does someone know a library that I can use to read MP3 tags in Silverlight 3?
In WPF I was using taglib, but obviously I cannot reference it in Silverlight projects.
Taglib doesn't contain any unsafe code. Perhaps you can recompile it (with a few minor alterations maybe) to work in silverlight.
Have you tried just using Taglib's code? There's a decent chance it'll work without too much hassle.
Edit: Yes, I mean TagLib#. I just tried, and there are a few minor issues which were fixable in 15min. (You'll need to define ICloneable, remove a bunch of unnecessary Serialization constructors for exceptions, remove the last parameter on string.Split(char[],int) calls, that's about it.)
Note that unless someone else has fixed it, there's a minor bug in Taglib#'s Id3v2 unsynchronization code. You can ignore it and fail to parse a few id3v2 tags, or you can use the same workaround I did: https://bugzilla.gnome.org/show_bug.cgi?id=593138#c4 - I know, I should submit a patch, but time and all...

Are there any limitations on what libraries can be imported in a t4 template?

We're trying to learn to use T4 Templates. I have a desire to use the System.Data.Entity.Design.PluralizationServices library in order to better pluralize some Entity Model names within my template, but I've come across some issues in the achievement of this goal.
Running code to generate output text. I think this is possible, but if it's not going to work, then there's no need to go any further. (I could call Date.Now.ToString() and get the expected result. I haven't tried anything much more complicated yet)
I am in a Silverlight App, and so I can't add a reference to the project for the PluralizationServices library in the place where I need the generated .cs file. I was planning on just moving the .tt file to a non-SL app, using the namespace and moving the generated file to the correct space. Haven't got that far yet, so I don't know how much trouble that will be, but it doesn't seem like it should be too hard.
My current problem is that when I import the namespace of the library, I get an "ErrorGeneratingOutput" and I haven't been able to move on past that yet.
I am having a hard time finding information about how the import command works, so I assume that it's just obvious. At the same time though, this one doesn't work so I wonder if it might be an exception to the standard.
<##import namespace="System.Data.Entity.Design.PluralizationServices" #>
I have no idea why adding this line (and only this line) causes everything to break. I haven't even started to try to use it yet! Is there something somewhere about libraries in T4 that I should know or read? Thanks!
Here a description of how the import directive works. Without knowing the actual error T4 reports when transofrming the template in your environment, I can only guess that you didn't add an assembly directive to reference the System.Data.Entity.Design assembly. If this doesn't work, look at the errors reported by T4 in the Error List of visual studio, which should be more helpful than "ErrorGeneratingOutput".

Resources