Format XAML UserControl and Window attributes on seperate line - wpf

In Visual Studio, I would like to configure the formatter such that UserControl or Window tags have their attributes on separate lines, but all other types have their attributes on the same line.
The standard formatter configuration places all the xmlns attributes into a long (and rather unwieldy) statement, which makes the code hard to read.
I've tried the formatter options, but the best I can get is to have attributes for all types on separate lines, which leads to untidy Setter blocks.
Is this possible in Visual Studio 2013?

You can use the XamlStyler plugin to format your XAML according to self-defined rules.
XamlStyler specific options.
Define your own attribute ordering rules
Define your own attribute line break rules
Markup extension formatting
Automatically reformat Xaml file on saving

Related

Convert Baml file into usable XDocument for parsing

I want to be able to write unit tests against Xaml to look for improper patterns. We have issues where the Xaml is still valid and otherwise compiles and "works" fine but can cause hidden issues or lacks consistency. In order to help combat this we want to write unit tests against the files.
A simple example: If you define a grid and the grid column is bound to a numeric field on the underlying object then the column title of the grid should have the appropriate right align template per our internal standards. Leaving the template off the definition will yield a left aligned column header which doesn't really break anything other than our internal standards. Given this is basically xml, I should easily be able to write a test that interrogates the xml element, detects the existence of a numeric column and checks to make sure that the file also defines a title template that is right aligned. This way I don't have to rely on the developer or QA to cover things that are easily testable like this.
I have access to the assembly during the unit test process and can get to all the baml resource files by reading the manifest resource stream. But I can't figure out how to read them into a useful format that I could load into something like an XDocument for parsing and perusing. Has anyone done this? I've tried using Baml2006Reader, etc... without any good success.
If you want to convert BAML to XAML, you could take a look at the following BamlTranslator class on GitHub.
It uses a BinaryReader to decompile the BAML.

XMLNS : a way to set them once for all?

We have multiple namespaces and assemblies in my project, and so many xmlns to declare in each control we make (at least 7, without system ones like x: or d:). It's so tedious.
Is there a way to declare xmlns once for all in the application ?
If not, do you have some workarounds (in order to have a lightweight control definition) ?
Please note that I know XmlnsDefinitionAttribute, it's not always possible (with external ssemblies for example) or not a great design (for me it's not a great design to put an UI specific attribute in a business entity assembly).
xmlns are a document level thing needed by the compiler, they are like using statements which you will also have to place in every C# code file.
If you have many common xmlns you could create an item template for Visual Studio which adds them by default, or find an extension which allows for something like Snippets in XAML.

What does the d:IsControlPart attribute do in Expression Blend?

In Expression Blend 4 the Simple Styles use the following XML namespace:
http://schemas.microsoft.com/expression/interactivedesigner/2006
It frequently uses an attribute from this namespace called IsControlPart which is a boolean. I've googled extensively and can't find any actual documentation on this attribute.
I think I figured it out.
When WPF creates the default templates for its controls, it names some of the elements with the prefix "PART". For example, with a Slider control, it has two parts, PART_Track and PART_SelectionRange. This in itself has nothing to do with Expression Blend.
These parts necessary for the basic functionality of the control. Most simple controls, like a Button, do not have any parts, so they can be fully customized without having any restrictions.
More complex controls rely on parts being present in order for the code-behind to work properly. It doesn't care what the control looks like, or where they are in the visual tree, so long as they exist and are of the right type.
In Expression Blend, there is a "Parts" window which is by default a tab alongside the "Project" and "Assets" tabs. When you are editing a template for a Control, if there are any parts defined for that control it lists them in this Parts window. It shows a check mark if that part exists in the current template, and if not you can double click on it and Blend will create the element for you.
I am still not sure exactly how the d:IsControlPart attribute works. I tried making my own custom Control and creating a element with the IsControlPart tag, and then creating a template for that control to see if it would list the part. It didn't. So this is still not 100% answered.

Serializing WPF RichTextBox to XAML vs RTF

I have a RichTextBox and need to serialize its content to my database purely for storage purposes. It would appear that I have a choice between serializing as XAML or as RTF, and am wondering if there are any advantages to serializing to XAML over RTF, which I would consider as more "standard".
In particular, am I losing any capability by serializing to RTF instead of XAML? I understand XAML supports custom classes inside the FlowDocument, but I'm not currently using any custom classes (though the potential for extensibility might be enough reason to use XAML).
Update: I ended up going with RTF because of its support for text-encoded embedded images. XAML doesn't seem to include image data in its encoding, and XamlPackage encodes to binary, so RTF just works better for me. So far I haven't noticed any lack in capability.
If all your users are doing is typing in the RichTextBox and doing character formatting, RTF is as good as XAML. However there are many FlowDocument capabilities you may expose in your UI that are not convertible to RTF.
Here are some examples of FlowDocument (and RichTextBox) features that are not expressable in RTF or are implemented differently:
A Block can have an arbitrary BorderBrush, including gradient brushes with stops, VisualBrush
A Section has the HasTrailingParagraphBreakOnPaste property
Floater / ClearFloaters is implemented differently
Hyphenation can be enabled/disabled per block, not just per paragraph
WPF Styles and ResourceDictionaries can be included in the Resources property
Arbitrary WPF UI such as bound CheckBoxes, etc, can be embedded inside the RichTextBox and can be cut-and-pasted from other windows.
For example, suppose you want to allow users to drag or cut/paste in a "current date/time" field into your RichTextBox that would always show the current date and time. This could be done by adding a second read-only RichTextBox that has the InlineUIContainer and the already-bound control. This even works when cutting and pasting from other applications and does not require custom controls.
Another consideration is that the code to convert between FlowDocument and RTF is relatively complex so it may have lower performance than going with XAML. Of course loose XAML doesn't include images and such - for that you need to use XamlPackage. I store my XamlPackage in the database as a byte[], but you can also choose to Base64 encode it for storage as a string.
The bottom line is that it really depends on whether you want the user to be able to use features not available in RTF. Even if your application doesn't include tools to generate FlowDocuments that use these features, it is possible to cut-and-paste them from other applications.
Be aware that in Wpf RichTextBox's method called TextRange.Save has a bug whereby it loses any end of line terminator. Microsoft will not fix.
https://connect.microsoft.com/WPF/feedback/ViewFeedback.aspx?FeedbackID=478640&wa=wsignin1.0#tabs

Why can't I use the Name attribute on UserControl in the same assembly?

When I created a WPF UserControl and tried to use it, I got the following compiler error:
Because 'UserControl1' is implemented in the same assembly, you must set the x:Name attribute rather than the Name attribute.
The message is clear on what to do to fix it, but what is its cause? Why can't I use Name here?
x:Name is simply a more explicit way of saying "The name attribute in this specific XML namespace". The fact that WPF can't compile it without being given this hint because it's in the same assembly is just a limitation of how they wrote the parser.
If you are asking why it is this way, I do not know for sure because I didn't write it. It probably has something to do with it needing to be able to resolve the Name attribute (read: Dependency Property) to something concrete BEFORE building your UserControl1, in other words, a catch-22.
In the beginning the XAML compiler was written to enable to creation of “trees” of .net objects, there were 101 projects within Microsoft that used XAML. The XAML compiler does not know anything about WPF.
The “Name” property is defined by WPF and is not known about by the XAML compiler. WPF maps the name property to be the same as the “Name TAG” that is supported by the XAML compiler. The “x” in “x:name” is saying use “name” as defined by the XAML xml schema, “Name” says find a property called “name” on the given object. See In WPF, what are the differences between the x:Name and Name attributes? for more details.
The XAML compiler is very limited in what it can do with a user control without having to load the assembly that defines the user control. As the XAML needs to be compiled before the assembly can be loaded, the xaml compiler clearly can’t load the assembly for a control that is implemented in the same assembly. Therefore the XAML compiler does not even know the item is a user control.
Properties that are defined on a user control (or its parent class) can therefore not be accessed. “Name” is a property that is defined in the parent (or super-parent) of a custom control.
The XAML compiler could just say “Name is not defined as a property”; if it did, think about how many people will fail to get a simple custom control working! Therefore the XAML compiler has a special case that gives a more useful error message, by “guessing” what the code means. Its guess are mostly correct.
Anything apart from the most simple user control needs to be in its own assembly, however user simple control are so common that a special case was considered worthwhile for them.

Resources