Basically, I remember that there was a time when you could use the following: <?Mapping ... > (It doesn't seem to work anymore -- Deprecated perhaps?)
I know I can map my XML namespaces like so...
xmlns:xyzcon="clr-namespace:XYZ.Wpf.Controls"
xmlns:xyzcom="clr-namespace:XYZ.Wpf.Commands"
But, I also know that I can map my XML namespaces like so (much cleaner)
[assembly: XmlnsPrefix("http://schemas.mycompany.com/netfx/xaml/presentation", "xyz")]
[assembly: XmlnsDefinition("http://schemas.mycompany.com/netfx/xaml/presentation", "XYZ.Wpf.Controls")]
[assembly: XmlnsDefinition("http://schemas.mycompany.com/netfx/xaml/presentation", "XYZ.Wpf.Commands")]
which makes it very easy to use because instead having the l, lv, etc. prefix I can have all my CLR-Namespaces point to the same XML namespace...
xmlns:xyz="http://schemas.mycompany.com/netfx/xaml/presentation"
That line gives me access to XYZ.Wpf.Controls and XYZ.Wpf.Commands. The problem is that this only works if the assembly is already compiled. I can't use this trick when working within the same assembly.
Basically, from within the same app or assembly, I want to map different CLR namespaces to the SAME XML namespace on a global scale (that way throughout my app I simply have to include that one XML namespace). Any way to do that?
It appears that there is still no way to map local namespaces within a WPF project. The book Programming WPF: Building Windows UI with Windows Presentation Foundation (published in 2007) states:
WPF projects in Visual Studio cannot use namespaces introduced by XmlnsDefinitionAttribute from XAML that live in the same assembly. If you want to refer to locally defined types, you must use the alternative mechanism...
The "alternative mechanism" being the dreaded xmlns:local="..." for each namespace.
My understanding is that the executing assembly (in this case the local WPF assembly) searches all referenced assemblies for both XmlnsPrefixAttribute and XmlnsDefinitionAttribute but does not search itself. It makes no sense that 4 years later this behavior has not changed, but that appears to be the case.
Related
Why should we use those, rather than ordinary ones?
what's the benefits of using this:
new Uri("pack://application:,,,/File.xaml");
over that:
new Uri("/File.xaml", UriKind.Relative);
The first one - you can use cross-assembly by adding a assembly-name after the three commas. So, you can create a shared library with common styles and other XAML-goodness that can be shared between several assemblies.
Syntax is like this:
pack://application:,,,/Common;component/CommonResources.xaml
where Common is the name of the assembly and everything after component is the path inside that assembly to the mapped resource. The latter can only be used inside the same assembly (and should be preferred).
I use it a lot for ResourceDictionaries residing in a common assembly above several module-type assemblies.
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.
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".
I'm currently using a lot of the same subclassed objects with custom methods. It would be more convenient to create my own library which I can use for several projects.
The goal is to have my own classes being available in the same way classes like UIView, CGRect etc are, including convenient methods like CGRectMake, both with classes and structs. To sum it up, I want to create my own equivalents of:
Classes like UIView
Structs like CGRect
Convenient functions like CGRectMake
Have this available as a library
Have this available as an XCode template, thus, having these custom Objects available as 'new files' in XCode
So basically I'm looking for instructions on how to create classes, structs etc in order to create all the above. What is the best way to do this? The 320 project seems like a good starting point. But it lacks (I think) in:
having the library available in new projects right away
having the new classes available under 'new file'
Even if I would create an own static library, will I be able to release the app on the app store, since linking to 3rd party libraries is not supported on the phone?
For your convenience, these are basically the sub questions, covering the scope of this question:
How can I create my own library for Mac / iPhone development?
How do I create classes, structs and inline function for this library?
How do I create my own Xcode template based on this library?
Will I be able to release iPhone apps using my own static library?
FYI Xcode 3.2 has a new project template called Cocoa Touch Static Library. You might want to go that route.
If you were doing this for a Mac, you'd create a framework. However, you mention UIView, so obviously you're working with the iPhone. Apple doesn't allow iPhone applications to dynamically link against other libraries at runtime, so your only option is to create a static library. A static library is linked into the application executable when it's built.
To my knowledge, there's no static library project template in Xcode. What you'll likely have to do is start with a different iPhone Xcode template and add a Static Library target. Hang on to the default application target; you can use that to build a simple test application to make sure the library actually works.
To actually use the library in an application, you'll need two things: the compiled library (it has a .a extension) and all the header files. In your finished application, you'll link against your static library, and you'll need to #import the header files so that the compiler understands what classes, functions, etc. are available to it. (A common technique is to create one header file that imports all the others. That way, you only need to import a single file in your source files.)
As for creating your own custom templates, there's a simple tutorial here that should get you started: http://www.macresearch.org/custom_xcode_templates You can probably copy the default templates and just customize them to suit your purposes.
The struct syntax looks like this:
typedef struct _MyPoint {
CGFloat x;
CGFloat y;
} MyPoint;
Structs are are declared in header files, so you can (I believe) Command+Double Click on the name of a struct to see how it's declared.
Another little trick for creating structs is to do something like this:
MyPoint aPoint = (MyPoint){ 1.5f, 0.25f };
Because the compiler knows the order of fields in the struct, it can very easily match up the values you provide in the curly braces to the appropriate fields. Of course, it's more convenient to have a function like MyPointMake, so you can write that like this:
MyPoint MyPointMake(CGFloat x, CGFloat y)
return (MyPoint){ x, y };
}
Note that this is a function, not a method, so it lives outside of any #interface or #implementation context. Although I don't think the compiler complains if you define it in an #implementation context.
CGPointMake is defined as what's known as an inline function. You can see the definition for that in the Cocoa header files, too. (The difference between an inline function and a normal function is that the compiler can replace a call to CGPointMake with a copy of CGPointMake, which avoids the overhead of making a function call. It's a pretty minor optimization, but for a function that simple, it makes sense.)
The 320 project is a good example of an iPhone class library. You basically compile your project down into a .a library and then statically link against this in your client projects.
Since this is a community wiki now, I thought it will be helpful to link some resources and tutorials:
http://blog.stormyprods.com/2008/11/using-static-libraries-with-iphone-sdk.html
http://www.clintharris.net/2009/iphone-app-shared-libraries/
Enjoy!
The 320 project seems like a good starting point indeed. But it lacks (I think) in:
having the library available in new projects right away
having the new classes available under 'new file'
Those are project and file templates. For more information, ask the Google.
If you plan on releasing this on the app store, you wont be able to use your library in the way that you would like. As mentioned above, linking to 3rd party libraries is not supported on the phone. I think there is a 'hack' way to make it work, but you'll lose distribution.
The best I could come up with was putting all the relevant code in a directory and sharing it that way. I know its not as elegant, but its their limitation ie. out of our control.
I am trying to add Silverlight support to my favorite programming langauge Nemerle.
Nemerle , on compilation procedure, loads all types via reflection mainly in 2 steps
1-) Uses Assembly.LoadFrom to load assembly
2-) Usese Assembly.GetTypes() to get the types
Then at the end of compilation it emits the resolved types with Reflection.Emit.
This procedure works for all assemblies including Silverlight ones except mscorlib of silverlight.
In c# this fails:
var a = System.Reflection.Assembly.LoadFrom(#"c:\mscorlib.dll");
but this passes :
var a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(#"c:\mscorlib.dll");
Bu in the latter , a.GetTypes() throws an exception sayin System.Object's parent does not exist.
Is there a way out ?
Assuming you're trying to reflect over Silverlight's mscorlib from the standard CLR, this won't work because the CLR doesn't permit loading multiple versions of mscorlib. (Perhaps this is because it could upset resolution of its core types).
A workaround is to use Mono.Cecil to inspect the types:
http://mono-project.com/Cecil. This library actually performs better than .NET's Reflection and is supposed to be more powerful.
Here's some code to get you started:
AssemblyDefinition asm = AssemblyFactory.GetAssembly(#"C:\mscorlib.dll");
var types =
from ModuleDefinition m in asm.Modules
from TypeDefinition t in m.Types
select t.Name;
You can compile Nemerle with Silverlight assembly and then you have Nemerle working on top of Silverlight :)