• Blog Moved

    During LonghornBlogs' absence, I moved my blog to a new location: http://fortes.com/work.

    If you're subscribed via RSS, you can use http://fortes.com/work/feed

    PostTypeIcon
    3,484 Views
  • What Happened to SimpleText?

    Amit Bahree asks :

    I was curious as to what happeend to the class SimpleText in the WinHEC build? If I have any code that ran on the earlier build - now does now and I get an exception on SimpleText.

    We removed SimpleText from the builds a short while after the PDC. You should use the Text element instead. We introduced the Text.TextContent property (of type String) after the PDC to provide easy support for binding (we also provide some storage optimizations when displaying a simple string of text.

    We already see a significant amount of user confusion between Text and TextPanel, having a third text control was a bit much (we'd like to only have one, but there are some performance and implementation issues that make that difficult to achieve). SimpleText was introduced as a stopgap to provide good performance and databinding capabilities for displaying text before the PDC, once the functionality was made available in Text, we removed SimpleText.

    PostTypeIcon
    3,235 Views
  • DockPanel.Dock

    Filed under: ,

    Karsten's Avalon Gotcha Quiz (and answer) points to a common source of confusion for DockPanel users:

    When Avalon encounters the "Fill" command, it does just that -- filling the entirety of the given element no matter what follows that element. So though I logically expected the placement of the following TextPanel to carve its location, it gets overriden by the earlier Fill command.

    DockPanel lays all of its children out in markup order (i.e. the order in which they appear on the Children collection), so if you tell a child to Fill it will take up all the remaining space, even though other children still remain.

    Another strategy (which other toolkits have done) is to go in a fixed order when docking, i.e. first layout all children that are docked top, then bottom, then left, etc. This makes some scenarios impossible without nesting DockPanels (e.g. Left, Top, Right), and did not provide clear gains for developers.

    Docking Fill children last would be inconsistent with the behavior of other values, but it seems to be what many users expect.

    We've been considering this change, any thoughts (pro or con)?

    PostTypeIcon
    2,900 Views
  • Text, TextPanel, and ContentElements

    Filed under: ,

    In response to a Performance Tip by Markus, Iain asks:

    Is a Bold object little more than a Text object with an inherent formatting clue?

    Quoting myself from a previous post:

    Classes such as Image and DockPanel are responsible for their layout and rendering. This works fine for a simple class such as Image, which does not need to break across lines and cannot intelligently break across pages.

    In contrast, classes such as Bold and Italic, are not responsible for their layout and rendering. Layout and rendering are instead handled by the parent TextPanel (or another element which can layout and render text content). There are a variety of reasons for doing this, but the relevant reason is that TextPanel wants to be able to break the contents of a Bold or Italic tag across lines. (Of course, we could hook up the right APIs and enable these classes to perform their own layout and rendering, but this would mean more work and less performance)

    The Bold element is actually an InlineElement with default formatting (FontWeight to be precise). Unlike Text, the Bold element is does not perform layout, instead it provides properties to a text range.

    Back to Markus' performance tip, why is the first example cheaper than the second?

    <Text FontWeight="Bold">Hello!</Text>
    <Text><Bold>Hello!</Bold></Text>

    The Text element has two methods for storage, depending on the nature of its content:

    • String: If the Text element doesn't contain any other elements, then Text will use a string for storage
    • Text tree: This is used when the element contains additional elements, such as Bold or Image, along with the text content. This tree is faster for formatting multiple runs of text, however there is a performance hit upon initialization for this tree

    If the entire Text element has the same formatting, we can optimize by using a string for storage; the use of the Bold element in the second markup example forces Text to use the more expensive text tree, thus causing a slight performance hit.

    (I don't believe this optimization is in the PDC build, it may have been checked in a couple of weeks after the PDC)

  • Additionally, the second example instantiates an extra class (Bold); this isn't a huge performance hit, but every little bit counts

    Editors Note: I realize it's been a while since I last posted. I'm trying to get back into the blogging habit, if you'll take me back. Baby, I didn't mean it! You know I still love you!

PostTypeIcon
5,140 Views
  • Breaking Across Pages

    Filed under: , ,

    This is an old post from my previous blog; unfortunately, the content was never ported to this blog. I'm re-posting it here so I can reference it in the next post.

    James Clark asks a couple of questions about pagination in my comments:

    Obviously a single paragraph has to be able to broken across multiple pages. How do TextPanel and block-level elements interact to allow this? Is it possible for a Table to split over multiple pages?

    Short answers: In most cases, TextPanel is responsible for the layout and visual representation of its contents. When this is not true (as with Table), there are optional interfaces which a class can implement in order to support breaking across pages.

    Long answer: I don’t have time right now to go into too much detail, so this will be brief (and incomplete). If there’s interest in this area, I can go into more detail in future entries.

    Classes such as Image and DockPanel are responsible for their layout and rendering. This works fine for a simple class such as Image, which does not need to break across lines and cannot intelligently break across pages.

    In contrast, classes such as Bold and Italic, are not responsible for their layout and rendering. Layout and rendering are instead handled by the parent TextPanel (or another element which can layout and render text content). There are a variety of reasons for doing this, but the relevant reason is that TextPanel wants to be able to break the contents of a Bold or Italic tag across lines. (Of course, we could hook up the right APIs and enable these classes to perform their own layout and rendering, but this would mean more work and less performance)

    In the case of Paragraph, breaking its content across multiple columns or pages is the responsibility of the parent TextPanel, as Paragraph does not do its own layout and rendering. However, this is not the case with Table, or any other element which does its own layout and wishes to break across pages. If an element wishes to support breaking across pages, it can implement the IDocumentFormatter and IDocumentHost interfaces, which will enable it to be hosted in a paginated context.

    Also from the comment:

    The concept of "attached properties" looks like a new one. It seems like the idea is that an object of class X occurring as a descendant of an object of class Y can have a property P that is not understood by X but is understood by Y and is used by Y in laying out X.

    Attached properties allow any class to attach a property to any other class; it does not have to be a descendant. You’re correct that class X (the attachee) does not know how to interpret the property which was attached by Y.

    …What if X has distinct logical and visual trees (e.g. paragraph vs lines)? Presumably Y will be taking the visual tree produced by laying out X and be using that visual tree in laying itself out. If so, how does it get access to the properties attached to X's logical tree?

    Because TextPanel creates the visuals for the Paragraph lines, the scenario you’ve described doesn’t occur. In general, most layouts interact with their direct visual children, so they would be checking only the direct children for an attached property. (This is the case for layouts, which tend to have identical logical and visual trees, with the notable exception of text layouts)

    PostTypeIcon
    3,936 Views
  • Now Taking Requests

    Filed under: ,

    I'm going to blantantly copy Chris, and take requests for blog content. My expertise is Layout, but I can pass on requests for other areas to my coworkers.

    Proposed future topics:

    • Walkthroughs for building interfaces/documents using Avalon layout classes
    • Creating custom layout elements (e.g. a Panel which flows its children along an arc)
    • Avalon layout architecture (how, when, and where layout happens)
    • Design decisions: History, motivation behind design decisions
    • Reader suggestions

    I realize I haven't posted much in the past few weeks, I was quite busy with Post-PDC planning, etc. Don't get your hopes up quite yet though, I'm going on vacation for two and a half weeks next week, so new content won't appear until mid-December. On the plus side, I'll be all rested (and tan) and actually have time to write some in-depth content.

    Let me know what you're interested in hearing about.

    PostTypeIcon
    4,939 Views
  • Outputting Debug Text to the Console

    Filed under: ,

    Erik Ardvisson asks:

    ... [I]s there some way to be able to output debug text to the console? (I tried #define DEBUG and all that.) I ended up using a log file but that is a bit cumbersome.

    We have a bug in our .Target files which cause the debug info to not get passed into CSC. We needed a quick workaround for the PDC build; we placed a hack into your myapp.xaml.cs file. To get console debugging working, do the following:

    1. Change "Debug" to "DEBUG" (all caps) in MyApp.xaml.cs
    2. Add "using System.Diagnostics"
    3. Call Debug.WriteLine("Hello!")
    4. See the output in the console

    This shouldn’t be an issue if you’re using VB.

    What if you're not using MyApp.xaml.cs? Just make sure "#define DEBUG" is in one of your .cs files.

    PostTypeIcon
    2,832 Views
  • Custom Layouts in Avalon

    Filed under: , ,

    RichB asks:

    What sort of layout does Avalon limit me to? Can I add my own layout engines instead of the standard flow layout?

    Avalon doesn’t place any limits on layout, developers are free to write the layout algorithm of their choosing. How would you implement a custom layout? Well, first you’ll need a quick introduction to the Avalon layout APIs.

    Layout computation occurs in two phases: Measure and Arrange; these functions are introduced on the UIElement base class. Measure and Arrange are the primary means for parent-child layout interaction (other interfaces exist, but they are optional). These passes can be (over) simplified as such:

    • Measure: Parent asks child how much size it requires
    • Arrange: Parent sets child size

    This is easily illustrated with a simple element such as Image. The layout parent Measures the Image, which computes its “desired size” by reading the source file’s dimensions (say 100 x 100). The parent will later call Arrange to set the Image’s size, usually taking the Image’s desired size into account.

    In most cases the child requires information about its layout context. A TextPanel with various paragraphs of text needs to know a line length to use when wrapping text, otherwise you end up with text which extends far off to the side of the screen. That is why Measure has a parameter, “available size,” which is commonly used as a wrapping size for flow layouts. Available size is usually the size of the window, getting partitioned as we descend the layout tree.

    In summary:

    • Measure: How much size is needed given this available size?
    • Arrange: Set size

    The Measure and Arrange concepts are the bare minimum you need to know for participating in layout. FrameworkElement introduces common properties such as Height, Width, MinHeight, MaxHeight, etc which add some complexity to the story, but you now have a basic understanding of the API.

    Finishing Rich’s question:

    ...[W]ould I be able to plug a layout engine into Avalon which is capable of laying out the SQL Server ER Diagram - which lays out each table in a database connected via primary/foreign key relationships and arranged so that no entities overlap?

    You can write your own custom element which implements such a layout algorithm, aside from the logic which ensures that no entities overlap, the code should be fairly simple.

    PostTypeIcon
    3,778 Views
  • XAMLXAMLXAMLXAML

    Filed under: ,

    Chris Anderson has written a series of articles about XAML:

    1. A Brief History of XAML
    2. Is XAML just data?
    3. Of Styles and Styling
    4. Response in some XUL newsgroups
    5. More on Avalon Styling... and CSS
    6. Another view on XUL
    7. XAML and the Web
    8. Dynamic UI

    I was inadvertently propelled into the midst of the XAML / XUL comparisons with an early post I wrote. Chris Anderson’s site is a far better place for these discussions. I’m sure this topic will remain active in the community, but I’ll let Chris be the host.

    PostTypeIcon
    3,311 Views
  • Weblog, take 2

    Filed under:

    Hopefully this will be the last time I move this weblog; I apologize for the broken links, if I had any control over the server I’d setup the right redirects.

    Meanwhile, I'm not quite sure how to move over my entries such that they keep their timestamps and comments (again, the lack of control over the server hurts me here). (Update: Robert says there's a quick script we should be able to use to port the content over)

    We now return you to our regularly scheduled weblog, already in progress.

    PostTypeIcon
    1,850 Views