Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,520
|
Comments: 51,141
Privacy Policy · Terms
filter by tags archive
time to read 4 min | 626 words

WPF / Ayende Viewer: Part III

The application is now composed of three screens, main one (choose categories):

(Image from clipboard).png

Select a post in a category:

(Image from clipboard).png

And view the posts in a category:

(Image from clipboard).png

Notice that you can page between the posts, this enables a very quick browsing experiance.

I commited the changes to the Rhino Tools repository (here), so you can see how I did it (not very complex). That data arrives from a sqlite database called ayende.blog using Active Record, of course.

Additional features that I want to add:

  • Add search capabilities, so I would be able to search the content / titles. Probably using SQLite full text searches. Allow to view the page results and to page through them.
  • Add tagging support, allow to browse the tags and page through tagged posts.

Not a lot of feature, eh?

Except that I have this list of things that I want to fix:

  • Give a uniform UI for the buttons in the first two screens, probaly on par with the prev/next links on the last screen.
  • Figure out control templates and replace the links on the last screen with a real control (right now it is a TextBlock with an event on MouseDown).
  • Figure out how to factor the common header into a seperate header control.
  • Add a column with the number of posts in each category.
  • Use WPF Commands instead of doing things in the events.
  • Figure out a better way to do paging than just moving between all those pages. There are advantages to this approach, so I think that I will keep them.
  • Put a meaningful title on the page, so the back button menu will look nice.
  • Put a Home button on the titlebar that will get you back to the main screen.
  • Figure out if an a really long chain of pages is a memory leak in the order that I should do something about. Yes, it is a memory leak, probably need to use KeepAlive=false, in which case the page will be discarded, and a new instance will be used when stepping back to it. As this is the default behavior, no need to do anything about it.
  • Figure out if triggers can replace the checks for next item, prev item. There isn't a way to do this properly, because there is an if pos+1 == count invovled.
time to read 12 min | 2259 words

(Image from clipboard).png

"Categories:" is static text, the rest is generated via this code:

IAddChild c = Categories;//Categories is a Stack Panel with Horizontal Orientation

foreach (Category category in post.Categories)

{

      TextBlock block = new TextBlock();

      block.Text = category.Name;

      block.Style = (Style) FindResource("BigText");

      c.AddChild(block);

      TextBlock seperator = new TextBlock();

      seperator.Text = "//";

      seperator.Style = (Style)FindResource("BigText");

      seperator.Foreground = Brushes.Brown;

      c.AddChild(seperator);

}

Is there a way to do this via XAML and not from the code?

I would like to thank Tomas Restrepo for pointing me in the direct direction, this is indeed possible, like this:

<ItemsControl Name="Categories"

                    ItemsSource="{Binding}">

      <ItemsControl.ItemsPanel>

            <ItemsPanelTemplate>

                  <WrapPanel Orientation="Horizontal"/>

            </ItemsPanelTemplate>

      </ItemsControl.ItemsPanel>

      <ItemsControl.ItemTemplate>

            <DataTemplate>

                  <WrapPanel>

                        <TextBlock Text="{Binding Path=Name}" Tag="{Binding Path=CategoryId}"

                                       MouseDown="Category_Browse"

                                       Style="{StaticResource BigText}"/>

                        <TextBlock Text="//"

                                       Foreground="Brown"

                                       Style="{StaticResource BigText}"/>

                  </WrapPanel>

            </DataTemplate>

      </ItemsControl.ItemTemplate>

</ItemsControl>

Notice the ItemsSource="{Binding}", which tripped me at first. Also, note that I am binding the tag of the text blog to the ID of the category. I don't really like this, but I couldn't figure out how to bind to the current item itself.

time to read 1 min | 67 words

(Image from clipboard).png

I have no idea what happened, but I was working on an ASP.Net application (no un-managed code), hit the pause button in the debug menu, to see where the application is spending a lot of time, and I somehow ended up here. Hm... somehow I get the feeling that my team didn't write it...

time to read 3 min | 452 words

The comments says it all, I think:

public virtual void Cancel()

{

  /*

  * NHibernate trickery:

  * Position is mapped using where="IsCancelled = 0"

  * When we cancel a Position, we are logically deleting it.

  * This plays havoc with the 2nd level cache, because the Employee.Positions

  * is cached, and the Position with the cached Id can no longer be loaded from the  
  * database.

  * Employee.Positions is mapped using cascade="all" and inverse="true"

  * So, we can remove the Position from the Employee, which will make it work

  * with the 2nd level cache, but because it is mapped as inverse="true", it

  * will not propogate the change to the database, so when we save the Position,

  * its EmployeeId will not be modified.

  */

  IsCancelled = true;

  Employee.Positions.Remove(this);

}

 

Ayende Brower II

time to read 1 min | 107 words

Take a look at this. Again, I must say that I really like WPF model. All the hurdles that I had so far were entirely my fault, and no hoods yet.

(Image from clipboard).png

Next is to support accelerator keys, paging between posts in a category and a way to tag the posts.

I am mainly doing this because I want to be able to do a quick review of all the posts in a specific category, and decide if I want to do something more with them, by the way.

time to read 2 min | 252 words

David Hayden has a post (ASP.NET AJAX Web Controls - AJAX Experience Without Learning AJAX) that really bothers me. He talks about the different components that he tested for Ajax support, and conclude with:

I was thinking that the AJAX experience was going to be a lot of work, but my guess is that the control vendors are taking care of this for me. And, quite frankly, I didn't want to have to learn this technology in depth if I could get away with it.

Frankly, I would like to know as much about Ajax as I could get away with. The problem is that you can't escape from the complexity. You can wrap it, hide it, stash it in the attic and throw away the key, but it will come back and hunt you.

(Image from clipboard).png Complexity, meet Ajax, you are going to be best friends.

The law of leaky abstractions holds quite well for Ajax. Eventually, you will need to do something slightly beyond what is supported by the controls, or you will get an error that can't be fixed by setting a property somewhere, or you'll need to debug an issue. Those are the cases where the willful ignorance will come to haunt you.

time to read 5 min | 826 words

It looks like a lot of the people working on MonoRail has at least some RubyOnRails experiance, this means that there usualy a way for people coming from mostly WebForms background to map the concepts they know to the MonoRail lingo.

Just to set the record straight, MonoRail is runing on ASP.Net platform, no perl involved.

Here is a mostly random attempt to map some of those concepts, note that I am talking about views only here;

  • Master Page
  • Master Page with multiply content areas
  • View State
  • Page LifeCycle Events
  • User Controls
  • Server Controls

Feel free to add more subjects, and I'll try to answer them as well.

Master Pages:

Master Pages are a way to share a common look and feel between pages, without duplicating the HTML. In MonoRail speak, they are called layouts, and they are settable on a controller or action granularity (or directly through code, if that strikes your fancy).

Master Pages with multiply content areas:

But wait, you are using a master page that is filled with more than a single location (for instnace, the main content and a header). In MonoRail, the same functionality is provided using a main content area ( ${ChildOutput}, for instnace ) and the use of normal variables that are filled by the view using a capture for component, like this:

Main content
<?brail component captureFor { @id : "header" }: ?>
My Header
<?brail end ?>

And in the layout:

${header}
${ChildOutput}

The output of those will be:

My Header
Main Content

View State:

View state doesn't exists, and good riddance. The web isn't stateful, the framework shouldn't lie to you and say that it is. When you need state, we have a powerful set helper classes that help provide you with the functionality that you desire.

Page LifeCycle Events:

They don't exist either, along with their complexity and the head aches that they bring. MonoRail has the following happening in a request: before filters, action, after filters, view rendering. And you usualy can ignore the filters.

User Controls:

Sometimes called partials, subviews, or macros in MonoRail speak (although each has a specific meaning), they provide the same functionality. A simple example of using one may be:

<?brail OutputSubView("faq/grid", { @source : items }) ?>

MonoRial's views can be easily embedded in an assembly, so it is trivial to take those from project to project without having to copy the sources themselves.

Server Controls

Those are called ViewComponents in MonoRail, and they provide a set of UI services for the application. Because in MonoRail the views are not working in a complex object hierarchy, it means that the view components are free to do a lot of interesting stuff that are harder to do in the WebForms model. Take for example the CaptureFor component, which output its content into a variable, which can later on be used by different parts of the views / layout.

No, no perl involved.

WPF Impressions

time to read 3 min | 489 words

Since it is expected that I will learn WCF and use it extensively, I decided to take a look at WPF and see what I can do with it. Considerring that I am thinking about taking some of my posts and turning them into a series of recipes, I thought that it would be a good idea to start by creating Ayende Viewer.

(Image from clipboard).png

Not, it is not even half way complete, but it it looking good, isn't it?

Couple of notes about it:

  • It plays really nice with business objects, which make me really happy. No more DataSet-Driven-Databinding.
  • I took a look at the architecture and it looks delicious. Simple for the simple cases, possible for the complex cases. And (at least in initial exploring) I didn't find any welded hoods.
  • The tools sucks, but I say this as someone that things that it is better that the tools will be bad and the framework easy to use than the other way around. Microsoft, please, do so again in the future, give your RTM products 6 months - year in the field, before bringing the big UI guns, it will do wonder to the code quality.
  • I like the HTMLisque feeling of it...

Of course, me being me (otherwise who would I be?), I run into some interesting issues that I haven't been able to figure out for a while. It all started when I wanted to add a value conveter so I could see dates in a comprehensible form. I found out about IValueConverter, implemented it, and try to use it. No magic words could convince the application to run, it kept complaining that the type (which I just wrote) did not exists.

A long time later, I finally try to remove the reference to the converter from the XAML and compiled, it worked. Adding the references back immediately fixed this issue. As far as I can figure out, XAML is reflecting over the assembly and trying to find the type, since I haven't compiled my assembly since adding the type, it couldn't find it, and the XAML error broke my build.

Second was an issue where it would flat out refuse to acknowlenge that the resource that I added existed, some observations about the state of the moon later, I finally figured out that it is evaluating the XAML (or BAML) in order, and moved the resource defination to the top of the page.

Conclustion, I think that I will like it...

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. Challenge (75):
    01 Jul 2024 - Efficient snapshotable state
  2. Recording (14):
    19 Jun 2024 - Building a Database Engine in C# & .NET
  3. re (33):
    28 May 2024 - Secure Drop protocol
  4. Meta Blog (2):
    23 Jan 2024 - I'm a JS Developer now
  5. Production Postmortem (51):
    12 Dec 2023 - The Spawn of Denial of Service
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}