|
|
May 21 Scott Barnes has an interesting entry about Evangelism. In it he quotes Guy Kawasaki on his The Art of Evangelism - saying that "Look for agnostics, ignore atheists". Firstly, I agree with this point entirely - but I feel it should be renamed to "Look for agnostics, ignore theists". What Guy is really saying here is that if somebody already has a Tool/Product affiliation then it's hard to persuade them to use another tool instead. Taking the religious analogy further - I would say that atheists do not believe in affiliation with a product or tool. They have 'no belief'. To me, the analogy to religion is a little stretched. Religious evangelicals try to persuade people into believing in something that there is no evidence. They preach the use of faith. Whereas, technology evangelists preach the merits of tools and products based on evidence - which is very different. Who would adopt a technology based on blind faith? May 02 The news from MIX07 this week has been very interesting. After watching some of the breakout sessions I thought I would answer Nick Kramer and provide some feedback as to which controls and functionality to include in the final Silverlight 1.1 release. The decision here is between supporting something at the core level, supporting it as a standard additional DLL or leaving it to the community. Of course, the more interop between WPF and Silverlight the better, but the size of the download needs to be kept in mind. So, in general, my inclination would be to use the following as guidance: - Include as much of the plumbing as possible. Adding alternative, competing plumbing solutions on top of Silvlight could drift the design direction away from the solutions used in WPF.
- Ship the controls as an additional DLL. When I say controls I mean button, textbox, listbox, combo etc.. These file sizes should be very small if the infrastructure is shipped in the core product.
- Work out a way of caching signed DLLs for reuse by other apps. The assembly resolver should be able to check an assembly cache for already loaded assemblies. Nothing as fancy as the GAC, just a dynamic cache of loaded assemblies on a best efforts basis.
So, specfically - taking the above.... - Include in the core the infrastructure for ItemsControl, including the virtualization of elements, Panel templates etc.
- Include DataBinding, Styling and TemplateBinding. A must have for the MVC pattern to work in WPF and Siliverlight.
- Include basic Panel support, additional Panels could be added from other DLLs (imported with ListBoxes etc).
- Include the basic controls where the data that they model is unique - not the behavior. So, an ItemsControl should be included but the ListBox, ComboBox and even ListView can be included as a sample or left to the community. Abstract controls providing the base classes are more important than covering the basic traditional Windows controls.
I would also suggest including a new version of the assembly linker that works to intelligently link referenced assemblies together and removed unused functions. Without this I think the third party control support is going to be limited to source code distribution only. Who will want to include a 10MB Grid Control if you are only using 10% of the functionality? March 11
Linking to Rob Relyea again, this time he talks about "Using Ricciolo PaperBoy 0.2 (WPF RSS Reader)".
With the IE7 RSS platform writing an RSS reader has got a lot easier. Rob mentions that he typically uses IE7 to read his feeds - this is one thing I don't understand. My OPML file has about 200 blog entries, most of which update maybe twice per month. IE7 is next to useless reading these feeds because it doesn't aggregate news. This same fault applies to Ricciolo Paperboy. A news reader without aggregation to me is just like browsing my favorites but without the HTML formatting.
There is RikReader - http://11011.net/software/rikreader - which is also written in WPF, uses the IE7 feed engine and supports aggregation. It's not too bad too, and comes complete with its own HTML to flow-document converter. Like Paperboy, it's a little unstable with some feeds.
After using Google Reader for the past six months, I need to add hosted reading state to the list of requirements. That means that I want a central server to know what I've read and what I haven't. I also want to share items and flag items of interest. Also, like with Google Reader, I want to be able to read these feeds on my cell phone. So here's my must-have / nice-have list:
- Good reading experience - i.e. better than Google Reader's HTML effort.
- Aggregation (river of news) - preferably tagged, not hierarchical.
- Hosted reading state - ability to share reading state across machines and devices (as in Google Reader).
- Easy to install - Click Once or XBAP.
- Blog writing integration - e.g integrate to Live Writer or similar.
- Comment support - ability to show comments and subscribe to comment feeds (if they exist).
- Browse support - ability to view Memes and browse blog entries and trackbacks graphically (like Times Reader).
- Mobile support - integrating reader state (so I can monitor what feeds are new)
- Podcast/ Vidcast support - enclosure support. IE7 kind of has this already, but the enclosures go to the temporary Internet directory. A news reader is a good chance to fix this - just copy those enclosures to a perconfigured directory and do some transcoding in the background.
- Offline reading - something that Google Reader doesn't do.
So, all this could be added to Paperboy - and it should be fairly easy to do (apart from the hosting, but even that could be made generic with some sort of polled external internet based file). The only thing that stops me delving into CodePlex is the fact that I'm convinced Microsoft has a product waiting in the wings that will compete with Google Reader. The Microsoft Max team did some of this already and the Live.com home page is very much based on RSS. The (Times) Reader SDK must have the capability to render your own personalized newspaper - based on your feed database. Live Writer has quite a following, although this is a WinForms app - I don't think it would take much to integrate this into the mix.
So is the market that Google Reader holds worth going for? From a purely financial perspective probably not. For secondary effects, like winning the minds of influentials and the Web 2 community it has more merit. It might be essential for MS that somebody like Robert Scoble uses Microsoft Technology over Adobe's or Google's. March 08 Rob Relyea asks for feedback on WPF. In response, I've put together some of my top 10 pet grievances. I have to highlight that this list is relatively minor. The structure and modularity of WPF stands out over and above other frameworks... there is a lot of potential here.
- DataTrigger versus Trigger - I've never really understood why these two needed to be modeled differently. A DataTrigger can be used against non DependencyProperties, and a Trigger can be used between different parts of the Visual Tree (usually with DPs). But does that distinction really need to be made to the developer? Why not just call it a Trigger and let the Framework work out the details. What's more annoying is that the properties on the two elements are different. This inconsistency is evident in a few areas of WPF.
- Expressing Inter-object References - the DataTrigger, Trigger, Storyboard, Timeline elements and others all suffer from inconsistent ways of referencing other objects. In WPF you often need to relate one object to another. It could be for Binding, or for animating a property or triggering an action based on a value being set. The problem is that there are different ways to express these relationships in WPF.
Storyboard and DataTriggers use TargetName - the name of the element being manipulated. Binding uses various ways : - including matching on type, name, relative path etc.. The DataContext is a pure and simple reference, through which you can use a resource look-up or set it in code directly. My point is that there should be one way of expressing inter-object references and that's it. Having to name elements is not good, the PropertyPath object is useful and the expressiveness of the Binding element is very good. We need one solution that's the best of all worlds used consistently everywhere.
- Inconsistently Behaved Events - some of the events in WPF do not act in accordance with the CLR guidelines. For example, the LayoutChanged event is fired when any element changes its position in the window. Even if you only hook a textbox 5 levels down the visual tree - where it is never moved - you still receive a LayoutChanged event every time some other element is moved, resized etc. What's worse is that the 'sender' parameter for LayoutChanged is always null. This makes the event next to useless... which leads nicely on to the next problem.
- Storyboard and Timeline completed events - these are hard to manage in some circumstances. The problem with these is that there is no way to link the event invocation back to the object being animated or to the animation object itself. WPF actually clones the Timeline or Storyboard before the animation is started - and there are no properties (that I can see) that will give you access to the object being animated. This makes ad-hoc triggered animations on collections of objects difficult to manage. The solution that I use is to set a generated 'name' on the Timeline and use a Dictionary to look it up in the event handler.
- Panels - I think one thing that would make WPF easier to learn would be to simplify the role of each element. I wish all Panels were called XXXXPanel. I also wish that their role was restricted to laying out elements - and not part of the visual tree. Setting the background color of a Panel just doesn't make sense and blurs its real purpose. I think it's little things like this that make it harder for new users to adopt the technology.
- Custom animations - this is still an area that I haven't spent that much time digging around in - I've only reused other people's hard work. Every time I see somebody hook into the render override to calculate the new animation position (and not use the Dispatcher) it just feels so Win32. Is it not possible to write your own Timeline derived class that would perform custom animation based on the scene contents?
- More transparency - I'm talking about tracing what WPF and MILCore are doing. When a texture needs reloading then it would be nice to see it logged somewhere - with the reason why. Why was a re-render necessary etc... The solution here may be ETW - but I'm not sure we have the tools and a supporting MSDN article.
- Deployment - the story is better now that IE7 is being rolled out. The install still takes too long and is painful for the average XP user. I'm hoping Microsoft will start using their own technology and we will see a wider install base (something more than the now defunct Microsoft Max). What's concerning is what's coming next. With WPF 1.5 being talked about, how much is this going to hurt...? Please no more reboots.
- Mid-life crisis - another concern is memory bloat. The nature of WPF app's makes them prime candidates for mid-life crisis - meaning objects are held long enough to survive past a generation 1 collection, but cleared down and recreated frequently enough for this to become a real problem. Generation 2 collections are bad for some kinds of applications, they are also bad when users check out their process list to see which applications are being greedy with their memory. DataBinding and the way ItemsControls work help this to a certain extent, but would it be better to use a memory pool for all objects rather than newing them straight out of the heap?
- GPU versus CPU - one big plus point with WPF is the utilization of the GPU. This is a big win over the competition. One thing that I don't understand is the lack of GPU acceleration for certain operations. Bitmap effects is one that springs to mind - why isn't a pixel shader used here for hardware that supports it? Is it concern over the driver quality? I would like to see more use of the shader model in the future - particle effects and other GPU features. It makes great eye candy for demos.
- + 1 more - Guidance Needed - what was great about MFC and VB was that there was a set way of doing things. Basically everybody wanted to be like Office or Explorer. It was actually quite hard to be anything else - if you wanted to change the behavior of one of the common controls it could take weeks of effort. We now have the tools to give us much more freedom, but there are only a handful of real-life applications and no new established look and feel. The Web (in some ways) suffered from the same problem - standards were gradually established over time. We need the next 'Microsoft Office' or 'Amazon' or 'CNET' for WPF applications. You can just mimic Win32 - but then why not just use Win32?
Lastly, please fix the MSDN feedback site. It looks like the WPF team have stopped reviewing the feedback. The versions of WPF include the July CTP and Beta 2 - but nothing later! The list of operating systems doesn't even include Vista. Would be nice to submit feedback - especially now that this technology is getting in more developers' hands. September 03 Here's a few lessons learnt whilst developing WPF usercontrols, custom controls and custom ItemsControls. Failed to recognize Dependency Property or Attached Property. Make sure that the static property is defined for on the class it is being used. For a dependency property called 'Custom' with a default value of 1.0: public static DependencyProperty CustomProperty = DependencyProperty.Register("Custom", typeof(int), typeof(MyClass), new PropertyMetadata( 0, new PropertyChangedCallback(Callback)));
Also make sure that the class level accessors have been added:
public int Custom { get { return (int)GetValue(CustomProperty); } set { SetValue(CustomProperty,value); } }
For Attached Properties use RegisterAttached:
public static DependencyProperty CustomProperty = DependencyProperty.RegisterAttached("Custom", typeof(int), typeof(MyClass), new PropertyMetadata( 0, new PropertyChangedCallback(Callback)));
The public methods : public static void SetCustom(UIElement element, int value) { element.SetValue(CustomProperty, value); } public static int GetCustom(UIElement element) { return (int)element.GetValue(CustomProperty); }
Error Loading XAML after adding a Dependency/Attached Property
Check that datatype of the default value. Make sure that it matches the type of the property (1.0 for a double versus 1 - which is an integer).
Implicit Styles not being picked up for the custom control:
When defining a style with a key of the data type of the custom control all the settings are ignored.
First, check that the default resource key has been defined in the custom control. Add the following public static constructor, this indicates that the default style for this control should use the Type object of MyClass :
static MyClass() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyClass), new FrameworkPropertyMetadata(typeof(MyClass))); }
Also, do not set the Style property of the custom control in the XAML definition. To apply a default style use a local style definition with a key of the type object.
Your Custom Control is not being created as the item in the ItemsControl
To instruct an ItemsControl derived class to create a specific custom control for databound items you need to override two virtuals: protected override DependencyObject GetContainerForItemOverride() { return new MyClass(); } protected override bool IsItemItsOwnContainerOverride(object item) { return (item is MyClass); } August 06 Some further notes from David Allen's very good book - Getting Things Done. Stages of planning a project - Purpose – why are you doing the project?
- Principles – standards to which the project should meet.
- Vision / Outcome – visualize the successful outcome of the task.
- Brainstorm – hierarchy of tasks, considerations and ideas.
- Organize – into project plans
- Next Action – each project’s next task should be selected based on criteria of who is doing, priority and dependencies. This stage should constitute 90% of the project management role.
Preparation - Take two whole days to go through your ‘open loops’ – this is existing projects with open tasks. Expect the full collection process to take 8 hours and then another 6 hours to organize those items.
- Set-up a central work space as the hub for your organization. This should hold the record of task lists etc..
- Use the right tools – paper holding trays, paper, pens, post-its, stapler, calendar etc…
Filing System for Reference - Set-up a general reference filing system – this should hold ‘stuff’ that needs to be referred to in the future.
- Purge the reference file once per year.
Collecting - Gather all your ‘stuff’ before processing it.
- Start with physical gathering – desktop, mail, drawers etc…
- Then move to mental gathering…
- Brain dump your issues, ideas, project, tasks in a single non-structure long list. Include incomplete projects, bills to pay, proposals not started etc… etc…
Processing Stuff - Each item that you gathered should be classified as one of the following:
- It takes less than 2 minutes – Do It Now.
- It’s of now use and needs no action – trash it.
- It’s of use for reference at some point in the future – store in reference system (see above).
- It might require action ‘someday maybe’ – add this to a ‘tickler file’.
- It needs action but somebody else can and should do it – delegate it.
- It needs action by you on a specific date – put it in your calendar.
- It needs action by you as soon as possible – add it to your ‘next actions’ list.
Go through each task and add further tasks if there are dependencies and it cannot be done now. For example, the ‘next task’ list could end up looking like this: - Do tax return.
- Clear out closet.
- Complete project proposal.
- Going through each one may yield further tasks, some of which are ‘waiting for’ tasks being performed externally.
- Do tax return – cannot start because waiting for K1. So, add new task ‘waiting for K1’ as a dependency for ‘Do tax return’.
- Clear out closet – cannot start because you may be at work. The context of this task is ‘at home’.
- Etc.. etc..
Define your Projects A project is anything that requires more than one task. A project can have a priority – a task cannot. A project may start with an external ‘waiting for task’ – which means it can’t start yet. Organizing Files Each of the following lists of things that need to be stored as part of the workflow process: - Calendar – contains actions that need to be performed on a specific date.
- Action List – contains a list of actions that need to be done as soon as possible. Each are attributed to a project and have a context (which restricts when you can do it). They could also have an attributed energy level and expected duration – this will further help filter down ‘what’s next’ depending on available resources.
- Waiting For lists – actions that are external either delegated or performed by somebody else. These still need chasing but do not get done by you.
- Project list – list of projects with the goals of the project. This should be reviewed once per week. Not usually changed during the course of a day. This list can be hierarchical – with sub-projects. Projects are different to actions – you cannot ‘do’ a project.
- Project support materials – this is where project plans, project reference material, documents etc.. are kept.
- Reference File – this is where information that may be needed in the future is stored, usually not associated with a specific project.
- Someday/Maybe list – list of things that don’t need to be actioned any time soon. Like recipe ideas, possible gifts in the future etc… It’s possible to use a calendar or a tickler file to defer these items (see below)
What is a Tickler File? - A file with 43 sections.
- It contains one section for each day for the month ahead (starting with the current date).
- Then a section for each each month (starting with next month).
- Deferring an item (someday/maybe) means moving it to a specific file in the tickler file. This can be a specific date over the next month or a specific month over the next year. This is when the item is reviewed again
August 05 I've just finished reading the first part of the David Allen book. Here's a very brief summary of what I understood as the basics of GTD: Collect Process - Identify the incoming ‘stuff’.
- Ask yourself is it actionable YES or NO.
- If NO then categorize as follows: - it’s either trash bin it, or it will need action later incubate it, or it could be used for reference later.
- If YES then determine what the next action is resulting from this collected item based on the objective for the designated project that it belongs to:
- If it takes less than 2 mins then Do it Now
- If it takes longer can or should you delegate it?
- If not then defer it and add it to one of two lists :- do it as soon as I can, do it on a specified date.
Organize From the above lists need to be maintained to successfully organize collected items: - Trash – stuff that doesn’t concern you.
- Incubation – stuff that you cannot action but someday may be able to.
- Reference – stuff that you will need for reference at a later stage.
- List of projects – used to identify collected items into larger longer-term objectives. A project is defined as anything that requires more than one step.
- Project plans - tasks, schedules and milestones for these projects. This used to determine what the next action should be from a collected item.
- A calendar – for deferred tasks with a specific date on it.
- Reminder list – used for actionable items that can be done by you.
- Waiting list – used to remind to chase actions that have be delegated.
The calendar contains the following: - Time tasks – i.e. appointments.
- Tasks that need to be done on a specific time/date.
- Date specific reference data. Information that you know you will need on a specific date.
- The ‘Next Action’ process is key to organizing. Based on the collected item you need to work out how that item affected the ‘Next Action’ for that project.
- Next Action lists can be categorized based on where you are. For example “calls to make” category can be used if you are near a phone and have some spare time.
- Categorize the ‘someday/maybe’ list based on classification. E.g. ‘CDs that I want’ or ‘Seminars to take’.
- Capture in a sentence how you define success for one of these commitments. Then list out the tasks of how to achieve it. Success is defined as being off your task list.
Review - Check the calendar to items that were scheduled to happen that day.
- Check the Next Action list for items that need to be done next. This can be categorized on context (location) and project.
- Perform a weekly review that involves going though all the lists, dependencies etc. Check the process is working.
Do There are four models listed to determine what tasks to do next: - The Four-Criteria Model: - select based on context (where you are), time available, energy available, priority.
- The Three-Fold Model: - do predefined work, work as it shows up, defining your work.
- The Six-Level Model : - Current Actions (stuff you have to do), current projects (projects flagged as high priority), areas of responsibility (projects via commitment), 1-2 year goals, 3-5 year goals, life goals.
December 06 I'm a big fan of Brad Abrams blog, which among other things, covers the issue of API usability. One issue that was causing some discussion a couple of months ago was how to treat the Obsolete attribute i.e. as a warning or an error, by the compiler or by FX Cop. Now that some of the .NET projects are through two or more release cycles these problems are becoming real experiences. There are issues with "obsoleting" methods or properties because it causes real pain for library users, but sometimes it is necessary to expose new functionality or just simplify the interface. With the introduction of FXCop it would be nice to be able to fix all those public members that don't comply with the design guidelines - but giving this as a reason doesn't hold much sway with users. So then, why not make meta-data help more here than being just a flag ? What I mean is we could extend the Obsolete Attribute to provide a real reference to the new property/method or class replacing the old one. At the very least this would help use with renaming these identifiers. Taken another step it could also provide parameter mapping between old and new functions - providing defaults for new parameters. All is needed then is for the IDE to pick out these new Obsolete attributes, flag them as errors but also provide a little hyperlink in the error "change to new property/function XXXX". In the same as the normal Obsolete attribute, the old function would work - but the upgrade rate to the new identifier would be far quicker. A bit of thought needs to be put into how to format the constructor for the attribute, as it's tricky to model collections (for parameters). It might make a handy add-in, maybe Tools|Fix Obsoletes! December 03 To kick things off on this blog I thought I'd get straight down to it. This is all about using Reflection in .NET to set properties. The background is a requirement to set members of an object based on configuration data - the problem is that performance is a big concern. You see it posted around the web a lot - that Reflection is very slow, question is "how slow?". The tests below compare setting 4 properties on an object 30000 times each. Each test was run on .NET 1.1. Test 1 used simple property assignment. i.e. x.Property1 = y1; x.Property2 = y2; Test 2 did the assignment via reflection. In each case the property name was looked up inside the loop: x.GetType().GetProperty("Property1").SetValue(x,y1,null); Test 3 did the same as above but cached the PropertyInfo object outside of the loop. So inside the loop the only code executed would be: PropertyInfo1.SetValue(x,y1,null); Test 4 used a special select/case function to set each property. This is manual reflection implemented as a string based indexer in the class. Calling the property looks like this: x["Property1"] = y1; The results are as follows: Test 1: 6.636ms Test 2: 215.520ms Test 3: 111.876ms Test 4: 64.066ms This makes (in order of speed) the following conclusions: The select/case method is 10 times slower than normal property assignments. This would, of course, vary with the number of properties. The cached reflection assignment is next slowest, it being about 17 times slower than the property assignment. The reflection assignment with the name look-up is the next slower, this adds about the same cost again as the above. Conclusion, reflection is indeed quite slow. Surprisingly I would have thought that Test 3 would come out a lot faster than it did. If the runtime has the PropertyInfo object then surely it has the function pointer for the Property Set method.
|
|
|
|