The Dark Side of LINQ

.NET August 5th, 2008

I’ve been having mixed feeling for quite some time now regarding LINQ.
Sure it can make working with data sources a lot easier and it can definately save a lot of code…
But, what happens with the following C# foreach statement

List<KeyValuePair<string, string>> resultList = new List<KeyValuePair<string, string>>();
string[] paramsArray = parameters.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string p in paramsArray)
{
    int index = p.IndexOf('=');
    if (index > 0)
    {
        string key = p.Substring(0, index);
        string value = p.Substring(index + 1);
        resultList.Add(new KeyValuePair<string, string>(key, value));
    }
}

IEnumerable<KeyValuePair<string, string>> result =
    resultList.Distinct((p1, p2) => p1.Key == p2.Key);

Turns to this query:

var distinctPairs = (from keyValuePair in parameters.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
                     let index = keyValuePair.IndexOf('=')
                     where index != -1
                     let key = keyValuePair.Substring(0, index)
                     where !string.IsNullOrEmpty(key)
                     let valueText = keyValuePair.Substring(index + 1)
                     select new { Key = key, ValueText = valueText })
                             .Distinct( (p1, p2) => (p1.Key == p2.Key) )
                             .ToArray();

I don’t know about you but I find the first version a lot more approachable, readable and quicker to understand. The same code in LINQ is not shorter and looks simply looks Evil.

LINQ is like the force… It can be used to wonderful code that is simple and functional, but it also has the potential of producing cryptic code that’s hard to maintain.

Use it wisely and don’t be tempted for its dark side…

Tags:

Are You Designing for Bigfoot?

Design, Development July 25th, 2008

Consider the following (imaginary) conversation:

Programmer: What if a user will want the ability to sort the values in the report grid by columns?

Manager: We don’t need a dynamic grid for version one.

Programmer: But someone might want to sort the values! Users will expect to be able to sort values by clicking on the column headers…

Manager: We don’t have time to add this feature to our schedule. Can’t we consider it for a future release?

Programmer #2: I don’t think sorting makes sense here.

….

Sounds familiar? If you’ve been part of a product development team you’ve probably encountered this kind of feature debate before… maybe even quite frequently…

Programmers are trained to think about possibilities and logic terms, that’s why the logic of what “might” happened is irresistible to the programmer.
Alan Cooper describes this behavior in The Inmates are Running the Asylum:

Programmers call these one-in-a-million possibilities edge cases. Although these oddball situations are unlikely to occur, the program will whenever they do if preparations are not made.
Although the likelihood of edge cases is small, the cost for lack of preparedness is immense. Therefore, these remote possibilities are very real to the programmer. The fact that an edge case will crop only once every 79 years of daily use is no consolation to the programmer. What id this one time is tomorrow?

The manager can’t advance the argument with the force of reason as he has no way to logically contradict this programmer and so he’s left with the choice of giving up or using his authority, which is usually how these kinds of arguments end up.

The programmers concern with the possible can easily obscure the probable by loading the program’s interface with controls and functions that will rarely be used.

The problem with this entire argument lies in the fact that arguing about what users might expect is the same as asking “What does Bigfoot like for breakfast?”

Tintin_Yeti

Users come in many forms and shapes. Some are proficient with computers, some don’t even like them. Some are used to Microsoft UI and some work mainly on the Mac. Some require advanced control with the expense of simplicity and should would rather give advanced control away in exchange for a quick and simple way to perform their goals.

In order to avoid this kind of dead-end feature debates its useful to change the team terminology and work in terms of personas and their goals. Rather than thinking of users as an abstract, difficult-to-describe, amorphous group of people, personas instruct us to talk about specific users who have names, personalities, needs, and goals.
Understanding exactly who the users are and what they do with the software is essential to determine if a certain feature is actually required.

Do we really need to allow sorting the column? there’s no way of telling…  but if you know that we’re designing for Jeff, a CFO of a large enterprise, who would like to get his report in a fixed predetermined format then its probably a requirement not to do so…

A very good example for use of personas can be found in Nikhil Kothari’s post about where he describes three personas that were used by the development division at Microsoft while working on Visual Studio 2005:

We have three primary personas across the developer division: Mort, Elvis and Einstein.

Mort, the opportunistic developer, likes to create quick-working solutions for immediate problems and focuses on productivity and learn as needed.
Elvis, the pragmatic programmer, likes to create long-lasting solutions addressing the problem domain, and learn while working on the solution.
Einstein, the paranoid programmer, likes to create the most efficient solution to a given problem, and typically learn in advance before working on the solution.

The description above is only rough summarization of several characteristics collected and documented by our usability folks.
During the meeting a program manager on our team applied these personas in the context of server controls rather well:

  • Mort would be a developer most comfortable and satisfied if the control could be used as-is and it just worked.
  • Elvis would like to able to customize the control to get the desired behavior through properties and code, or be willing to wire up multiple controls together.
  • Einstein would love to be able to deeply understand the control implementation, and want to be able to extend it to give it different behavior, or go so far as to re-implement it.

Using the above described personas, Nikhil’s team was able to effectively design a set of .NET controls so that each persona will find them usable for his use:

All of these controls just work out of the box in implementing the end-to-end scenario of managing user sign-on. Coupled with themes, these controls can look pretty good as well. They go on to provide a whole set of properties to tweak their behavior, and appearance.

Furthermore, they provide the ability to flip into template mode for more significant changes to their content and layout.

Finally, they’re built on the provider-model in ASP.NET so an advanced developer could come along and swap out the built-in membership provider going against say the default SQL or Active Directory user database and replace it with one that goes against say an Oracle user database or some other custom store while keeping the UI functionality intact.

So, the next time you’re in a feature debate, stop and ask yourself “Who exactly am I designing this feature for? Why does he need it?”.
Describe a set of personas that your software will target and use them as reference in any design discussion or feature debate instead of referring to an amorphous group of “users” that might not even exist.

Don’t design your software for bigfoot….

Tags: , , ,

How Do You Define "Good Code"?

Development June 26th, 2008

I was on a phone interview the other day where I was asked for my definition of “Good Code”.

The first thought that came to mind was maintainability - if it can’t be understood, maintained and extended by other developers than its definitely not good.
Then, other things came to mind: efficiency, elegance (simple, proper use of language constructs and environment capabilities), modularity, proper object-oriented design, …
Of course, and we tend to take that for granted, it also has to work… without errors, security holes, etc.

In his book, Code Complete, Steve McConnel supports my definition of good code as maintainable code:

Another theme that runs throughout this book is an emphasis on code readability. Communication with other people is the motivation behind the quest for the Holy Grail of self-documenting code.

The computer doesn’t care whether your code is readable. It’s better at reading binary machine instructions than it is at reading high-level-language statements. You write readable code because it helps other people to read your code. Readability has a positive effect on all these aspects of a program:

  • Comprehensibility
  • Reviewability
  • Error rate
  • Debugging
  • Modifiability
  • Development time—a consequence of all of the above
  • External quality—a consequence of all of the above

Readable code doesn’t take any longer to write than confusing code does, at least not in the long run. It’s easier to be sure your code works if you can easily read what you wrote. That should be a sufficient reason to write readable code. But code is also read during reviews. It’s read when you or someone else fixes an error. It’s read when the code is modified. It’s read when someone tries to use part of your code in a similar program.

Making code readable is not an optional part of the development process, and favoring write-time convenience over read-time convenience is a false economy. You should go to the effort of writing good code, which you can do once, rather than the effort of reading bad code, which you’d have to do again and again.

On the other hand, Paul DiLascia, from MSDN’s {END BRACKET} column, provides a list of traits that good code should have:

Whether you code in C/C++, C#, Java, Basic, Perl, COBOL, or ASM, all good programming exhibits the same time-honored qualities: simplicity, readability, modularity, layering, design, efficiency, elegance, and clarity.

Simplicity means you don’t do in ten lines what you can do in five. It means you make extra effort to be concise, but not to the point of obfuscation. It means you abhor open coding and functions that span pages. Simplicity—of organization, implementation, design—makes your code more reliable and bug free. There’s less to go wrong.

Readability means what it says: that others can read your code. Readability means you bother to write comments, to follow conventions, and pause to name your variables wisely. Like choosing “taxrate” instead of “tr”.

Modularity means your program is built like the universe. The world is made of molecules, which are made of atoms, electrons, nucleons, quarks, and (if you believe in them) strings. Likewise, good programs erect large systems from smaller ones, which are built from even smaller building blocks. You can write a text editor with three primitives: move, insert, and delete. And just as atoms combine in novel ways, software components should be reusable.

Layering means that internally, your program resembles a layer cake. The app sits on the framework sits on the OS sits on the hardware. Even within your app, you need layers, like file-document-view-frame. Higher layers call ones below, which raise events back up. (Calls go down; events go up.) Lower layers should never know what higher ones are up to. The essence of an event/callback is to provide blind upward notification. If your doc calls the frame directly, something stinks. Modules and layers are defined by APIs, which delineate their boundaries. Thus, design is critical.

Design means you take time to plan your program before you build it. Thoughts are cheaper than debugging. A good rule of thumb is to spend half your time on design. You need a functional spec (what the programs does) and an internal blueprint. APIs should be codified in writing.

Efficiency means your program is fast and economical. It doesn’t hog files, data connections, or anything else. It does what it should, but no more. It loads and departs without fuss. At the function level, you can always optimize later, during testing. But at high levels, you must plan for performance. If the design requires a million trips to the server, expect a dog.

Elegance is like beauty: hard to describe but easy to recognize. Elegance combines simplicity, efficiency, and brilliance, and produces a feeling of pride. Elegance is when you replace a procedure with a table, or realize that you can use recursion—which is almost always elegant:

int factorial(int n) {   return n==0 ? 1 : n * factorial(n-1); }

Clarity is the granddaddy of good programming, the platinum quality all the others serve. Computers make it possible to create systems that are vastly more complex than physical machines.
The fundamental challenge of programming is managing complexity. Simplicity, readability, modularity, layering, design, efficiency, and elegance are all time-honored ways to achieve clarity, which is the antidote to complexity.

Clarity of code. Clarity of design. Clarity of purpose. You must understand—really understand—what you’re doing at every level. Otherwise you’re lost. Bad programs are less often a failure of coding skill than of having a clear goal. That’s why design is key. It keeps you honest. If you can’t write it down, if you can’t explain it to others, you don’t really know what you’re doing.

So what are the most important trait for “Good Code” ?
Later on, it struck me – like anything when it comes to engineering, its about balance.
When we write code we strive to find balance between complexity and simplicity by constantly evaluating the different tradeoffs we have to choose in order to get there.
Therefore, good code is code that strikes the right balance balance between all of the qualities mentioned above.

Think about it the next time you’re writing or reading someone else’s code…

Technorati Tags: ,,

Comments (2) imported from www.ekampf.com/blog/:

Tuesday, July 01, 2008 1:01:39 PM (GMT Daylight Time, UTC+01:00)

“On the other hand, I was using Google software - a lot of it - in the last year, and slick as it is, there’s just too much of it that is regularly broken. It seems like every week 10% of all the features are broken in one or the other browser. And it’s a different 10% every week - the old bugs are getting fixed, the new ones introduced. This across Blogger, Gmail, Google Docs, Maps, and more. “

As much I really like the simple but powerful UI of services like Gmail etc: Sometimes its really annoying to see bugs coming and going! The software seems never to get stable. And Google seems to be aware of this, at least they mark nearly all their apps with a BETA-tag :-)
It would be interesting to hear something about the software development process. Do they practice things like unit-tests, continuous integration, code reviews, etc.?

Florian Potschka

Tuesday, July 01, 2008 1:25:41 PM (GMT Daylight Time, UTC+01:00)

Hey Florian,
According to this and this its seems like a one big community where each project is managed like an open-source project.
From experience, having developers dividing their time between several projects (that can be unrelated as the post says) doesn’t work well…
Not much public information on their internal practices though… not sure if its a good sign :S

Regards,
Eran

Eran Kampf

Tags: ,

Developing a Robust Data Driven UI Using WPF - Stock DataModel Sample

.NET, Development, WPF March 30th, 2008

On the previous post in this series we looked into the DataModel component in our architecture in detail and defined an abstract DataModel base class to derive our models from. On this post we’ll implement a concrete data model to represent a stock’s value. Why stock? It’s an object with a changing value that requires our DataModel constantly refresh and keep its data “alive”, and it’s simple to implement which makes it a perfect example for our first DataModel. The first thing we’ll do when defining our Stock DataModel is abstract the data source. This way we can easily implement several data sources for fetching a stock’s data and instantiate the DataModel with the right one (for example, read from Yahoo at runtime, read from fake data source during unit testing):

/// <summary>
/// Defines the interface allowing <see cref="StockDataModel"/> to read quotes from various providers.
/// </summary>
public interface IStockDataProvider
{
    /// <summary>
    /// Gets a given stock symbol's (given by <paramref name="symbol"/>) data.
    /// </summary>
    /// <param name="symbol">The stock's symbol.</param>
    /// <param name="name">The stock's company name.</param>
    /// <param name="quote">The last stock's quote.</param>
    /// <param name="change">The stock's change value.</param>
    /// <param name="open">The stock's open value.</param>
    /// <returns><b>True</b> if data was retrieved successfully; otherwise, <b>False</b>.</returns>
    bool TryGetData(string symbol, out string name, out double quote, out double change, out double open);
}

Now that we have our data source defined we can implement different stock data providers for our DataModel to consume. Now, lets go over the StockDataModel class:

public class StockDataModel : DataModel
{
    private string _symbol;
    private IStockDataProvider _quoteProvider;
    public StockDataModel(string symbol, IStockDataProvider provider)
    {
        _symbol = symbol;
        _quoteProvider = provider;
        this.State = DataModelState.Fetching; 

        // Queue a work item to fetch the symbol's data
        if (!ThreadPool.QueueUserWorkItem(new WaitCallback(FetchDataCallback)))
        {
            this.State = DataModelState.Invalid;
        }
    } 

    public string Symbol
    {
        get { return _symbol; }
    }

Our StockDataModel constructor takes the stock symbol that the model represents and an IStockDataProvider to fetch the stock’s data from. We set the initial DataModel state to Fetching and queue a work item for a background thread to update our model with the stock’s data - company name, quote, change value and open value. If we fail to queue the work item than we put the model in an invalid state. Next, we need to define the properties exposed by StockDataModel for data binding.

public string Name
{
    get
    {
        VerifyCalledOnUIThread();
        return _name;
    }
    private set
    {
        VerifyCalledOnUIThread(); if (_name != value) { _name = value; OnPropertyChanged("Name"); }
    }
}
public double Quote
{
    get
    {
        VerifyCalledOnUIThread(); return _quote;
    }
    private set
    {
        VerifyCalledOnUIThread(); if (_quote != value) { _quote = value; OnPropertyChanged("Quote"); }
    }
}
...

 

We’re sign a private setter to update the property values and trigger a PropertyChanged event if required. You can also add calculated properties. For example:

public double ChangePercent
{
    get
    {
        if (double.IsNaN(Change))
            return double.NaN; 

        if (double.IsNaN(Open))
            return double.NaN; 

        try
        {
            double change = (Change / Open) * 100; return change;
        }
        catch
        {
            return double.NaN;
        }
    }
}

In this case, it is important to remember to trigger the property change event for ChangePercent too when the values it depends on change… Now for the implementation of the FetchDataCallback. This method will be called by a background thread to update the stock data. Since this method is called by a background thread we’re free to perform expensive operations, such as calling a web service to fetch the stock’s data from an online provider (like Yahoo).

private void FetchDataCallback(object state)
{
    string fetchedName;
    double fetchedQuote;
    double fetchedChange;
    double fetchedOpen;

    if (_quoteProvider.TryGetData(_symbol, out fetchedName, out fetchedQuote, out fetchedChange, out fetchedOpen))
    {
        this.Dispatcher.BeginInvoke(
            DispatcherPriority.ApplicationIdle,
            new ThreadStart(
                delegate
                {
                    this.Name = fetchedName;
                    this.Quote = fetchedQuote;
                    this.Change = fetchedChange;
                    this.Open = fetchedOpen;
                    this.State = DataModelState.Active;
                }));
    }
    else
    {
        this.Dispatcher.BeginInvoke(
            DispatcherPriority.ApplicationIdle,
            new ThreadStart(
                delegate
                {
                    this.State = DataModelState.Invalid;
                }));
    }
}

On the previous post, on the WPF threading model overview we noted the following:

If only the creator of a DispatcherObject can access it, how can a background thread interact with the user? The background thread does not access the UI directly but it can ask the UI thread to perform a task on its behalf by registering work items to its Dispatcher using it’s Invoke (for a synchronous call that returns when the UI thread finished executing the delegate) or BeginInvoke methods (which runs asynchronously)

In the above code, after fetching the data on the _quoteProvider.TryGetData we need to communicate these changes back to the UI thread. We use the Dispatcher to set the new values for the DataModel properties which ensures that our property change events will be triggered on the UI thread.

Keeping the Data Alive

So far, our code only fetches the stock data once. Lets see what it takes make out DataModel keep its data alive.

protected override void OnEnabled()
{
    _timer = new DispatcherTimer(DispatcherPriority.Background);
    _timer.Interval = TimeSpan.FromMinutes(5);
    _timer.Tick += delegate { ScheduleUpdate(); };
    _timer.Start(); 

    ScheduleUpdate();
}
protected override void OnDisabled()
{
    _timer.Stop();
    _timer = null;
}
private void ScheduleUpdate()
{
    VerifyCalledOnUIThread();
    // Queue a work item to fetch the quote
    if (ThreadPool.QueueUserWorkItem(new WaitCallback(FetchDataCallback)))
    {
        this.State = DataModelState.Fetching;
    }
}

The above code defines a timer that is active when the DataModel is Enabled. The timer calls ScheduleUpdate every 5 minutes to perform the same data update using a background thread logic we performed on our constructor. We’re using a DispatcherTimer so that the calls to ScheduleUpdate will be made using the Dispatcher’s thread (the UI thread) so that we can update the DataModel’s state without a hassle. If we had used System.Threading.Timer then ScheduleUpdate would be called on the timer’s thread requiring the use of Dispatcher.BeginInvoke to update the state…

That’s it…

We’ve got the basic DataModel implemented. You can using it in you’re XAML window to see it working… To get a basic XAML running you’ll need to define a content control:

<ContentControl x:Name="_content" />

And set its content to a StockDataModel instance on your codebehind:

_content.Content = new StockDataModel("AAPL", someProvider);

Then all you need to do is define a data template for the StockDataModel type to control it’s appearance. Here’s a simple template for example:

<DataTemplate x:Name="StockTemplate" DataType="{x:Type local:StockDataModel}">    <StackPanel Orientation="Horizontal" mdb:EnableModel.DataModel="{Binding}" Height="30px" Width="Auto" ClipToBounds="True">       <TextBlock Text="{Binding Name}" Foreground="#737271" Width="120" Padding="3,0,0,3" Style="{StaticResource StockText}" />      <TextBlock Text="{Binding Quote}" Foreground="#737271" Width="55" Padding="0,0,0,3" Style="{StaticResource StockText}" />     </StackPanel> </DataTemplate> 

You can find the code discussed in this article plus my own implementation for an IStockDataProvider that reads stock data from Yahoo here: On the next post we’ll discuss DataModel unit testing and see how the StockDataModel tests are implemented.

kick it on DotNetKicks.com

Comments (5) imported from www.ekampf.com/blog/:

Sunday, March 30, 2008 10:45:52 PM (GMT Daylight Time, UTC+01:00)

Thanks for the series! Looking forward for the following parts. However, there’s a bug in the shown code as you cannot check if a value is NaN by comparing to double.NaN. You have to use double.IsNaN(…).

Use IsNaN to determine whether a value is not a number. It is not possible to determine whether a value is not a number by comparing it to another value equal to NaN.

Simon Monday, March 31, 2008 4:39:37 AM

(GMT Daylight Time, UTC+01:00)

Hey Simon, Thanks.

Fixing the code and the post…

Regards,
Eran

Eran Kampf

Friday, April 04, 2008 3:47:12 AM (GMT Daylight Time, UTC+01:00)

Very nice article series. Keep up the good work!

Kevin Kerr

Wednesday, May 28, 2008 2:55:06 PM (GMT Daylight Time, UTC+01:00)

Really great series, very nicely done.

Question: Why call VerifyCalledOnUIThread() in the ScheduleUpdate method? Since you’re calling BeginInvoke on the dispatcher inside FetchDataCallback all should be well, right?

Mike

Thursday, May 29, 2008 11:41:31 AM (GMT Daylight Time, UTC+01:00)

Hi Mike,

  Good question. Notice that besides calling queuing a work item that calls FetchDataCallback, the ScheduleUpdate method also updates the model’s State to DataModelState.Fetching when that work item is queued. Since we’re changing the actual model we need to make sure we’re doing it in the UI thread. Alternatively, we could have used a System.Threading.Timer to do the updates ScheduleUpdate() will be called on a background thread directly, but then we couldn’t set the model state to fetching. We’d have to send that back to the UI thread.

Regards,
Eran Kampf

Eran Kampf

Tags: , , , ,

Developing a Robust Data Driven UI Using WPF - The DataModel

.NET, Development, WPF March 24th, 2008

imageIn the first post in the series I gave an overview of the pattern we’ll be using.
This post will go deeper into the DataModel, as defined in the previous post:

The DataModel is defined exactly as the Model in MVC; it is the data or business logic that stores the state and does processing of the problem domain.
The DataModel abstracts expensive operations such as data fetching without blocking the UI thread. It can keep data “alive” fetching it periodically from source (example: stock ticket), merge information from several sources etc.
The DataModel is completely UI independent and pretty much straightforward to unit test.

The DataModel exposes data in a way that makes it easily consumable by WPF. As such, all if its public APIs, called by WPF for data-biding, must be called on the UI thread only. It must not block the UI thread because we want a robust functional UI so it usually performs operations on a background thread using the Dispatcher to send results back to the UI thread.

Therefore, the simplest DataModel implementation exposes several public Properties that expose data, implements INotifyPropertyChanged and/or INotifyCollectionChanged, and it abstracts the way information is fetched (using background threads to avoid blocking the UI thread when fetching the data is an expensive operation).

For two-way binding a commit and rollback mechanism, a dirty flag, etc.&nbsp; We’ll get to that later on…

As the DataModel implementation needs to abstract expensive data fetching operations and work with multiple threads we need some basic understanding of WPF’s threading model before we look at the DataModel implementation…

WPF Threading Model - A Quick Overview

A typical WPF uses two threads:

  • Rendering thread - runs in the background and handles rendering
  • UI thread - Receive inputs, handles events, paints the screen and runs application code.

The UI thread queues work items in a Dispatcher object. The Dispatcher object selects work items on a priority basis and runs each one to completion.
Every UI thread must have at least one Dispatcher, and each Dispatcher can only use one thread to execute work items.

Therefore, in order to build responsive UI that doesn’t block the UI thread, the application has to maximize the Dispatcher’s throughput by keeping work items small as to minimize the time the Dispatcher spends on processing them - which keeps other work items waiting causing the UI to lag.

In order to perform expensive operations without blocking the UI thread we can use a separate thread that will run in the background, leaving the UI thread free to process items in the Dispatcher queue. When the background thread is done processing it can report results back to the UI thread for display.
Doing this isn’t trivial as Windows only allows UI elements to be accessed by the thread that created them. This means that the background thread we used for some long-running task cannot access and update our UI when it is finished (or during work to show progress) - a background thread updating a control (such as a list box) during its rendering can cause strange UI behaviors that this limitation is there to prevent.

WPF uses the following design to enforce this kind of coordination between the UI thread and other threads:
Most of the classes in WPF derive from DispatcherObject. During construction, a DispatcherObject stores a reference to the Dispatcher&nbsp;linked with the current running thread - creating an association between itself and the thread that created it.
At the beginning of every method in the DispatcherObject, it calls VerifyAccess which compares the Dispatcher associated with the current thread with the Dispatcher stored during the object’s construction - if they do not match it throws an exception.

If only the creator of a DispatcherObject can access it, how can a background thread interact with the user?
The background thread does not access the UI directly but it can ask the UI thread to perform a task on its behalf by registering work items to its Dispatcher using it’s Invoke (for a synchronous call that returns when the UI thread finished executing the delegate) or BeginInvoke methods (which runs asynchronously)

The DataModel Class

So now, after the brief discussion on the use of the Dispatcher we can start coding our base DataModel class.
We’ll start with the simple class and constructor definition:

public abstract class DataModel : DispatcherObject, INotifyPropertyChanged
{
    public DataModel()
    {
    }


We’re deriving from DispatcherObject because we need to have the Dispatcher available so that we can run background jobs that dispatch results to the UI thread.

As discussed earlier, each call to the DataModel should be made on the UI thread. Therefore we would like to enforce that limitation at the beginning of each publicly exposed API. The DispatcherObject class that we derived from contains a VerifyAccess() method that does just that. The method is public but unfortunately marked with the [EditorBrowsable(EditorBrowsableState.Never)] attributes which will make it hard to find for developers using driving their data model from our class.

To resolve this I simply defined a protected method as follows:

/// &lt;summary&gt;
/// Makes sure the call is in the correct thread (the UI thread) by comparing the current dispatcher
/// object with the dispatcher we got when the DataModel was created.
/// &lt;/summary&gt;
[System.Diagnostics.Conditional("Debug")]
protected void VerifyCalledOnUIThread()
{
    this.VerifyAccess();
}

This method will be visible to anyone deriving from our class and it simply calls VerifyAccess to make sure code is made from the UI thread.
The Conditional attribute makes this code execute only in debug bits avoiding this kind of assertion on retail bits - some performance gain.

In order to support asynchronous data fetching the DataModel should encapsulate the information about its state - valid (data fetched), invalid (error fetching data), fetching (processing).

public enum DataModelState
{
    /// &lt;summary&gt;
    /// The model is fetching data
    /// &lt;/summary&gt;
    Fetching,
    /// &lt;summary&gt;
    /// The model is in an invalid state
    /// &lt;/summary&gt;
    Invalid,
    /// &lt;summary&gt;
    /// The model has fetched its data
    /// &lt;/summary&gt;
    Active
}

The data model’s state is exposed using a property:

public DataModelState State
{
    get
    {
        VerifyCalledOnUIThread();
        return _state;
    }
    set
    {
        VerifyCalledOnUIThread();
        if (value != _state)
        {
            _state = value;
            OnPropertyChanged("State");
        }
    }
}

We also implement INotifyPropertyChanged to allow the model to communicate changes in its values.
Since adding\removing event handlers to the PropertyChanged event is a public API exposed by the DataModel, it also requires verification that calls to it are made from the UI thread. We’ll define our own add\remove handlers in order to perform this verification:

protected virtual void OnPropertyChanged(string propertyName)
{
    VerifyCalledOnUIThread();

    if (_propertyChangedEvent != null)
    {
        _propertyChangedEvent(this, new PropertyChangedEventArgs(propertyName));
    }
}

#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged
{
    add
    {
        VerifyCalledOnUIThread();
        _propertyChangedEvent += value;
    }
    remove
    {
        VerifyCalledOnUIThread();
        _propertyChangedEvent -= value;
    }
}
#endregion

Any property that we’ll add to our data model will call OnPropertyChanged on its setter in order to notify it has changed.

It’s Alive!

One more ability we’d like to add to our DataModel class is the ability to enable\disable it.
As defined earlier, the DataModel encapsulates the logic of fetching data and keeping it “alive” and up to date. To do that, it’ll need to keep some internal timer for updating information or register to some change notification event on its source.
This will keep the DataModel alive and can result in memory leaks, which is why we need some way to turn the DataModel on and off, allowing it to unregister from its data sources when that connection is no longer required:

public bool Enabled
{
    get
    {
        VerifyCalledOnUIThread();
        return _isEnabled;
    }
    set
    {
        VerifyCalledOnUIThread();
        if (value != _isEnabled)
        {
            _isEnabled = value;
            OnPropertyChanged("Enabled");
        }
    }
}

public void Enable()
{
    VerifyCalledOnUIThread();

    if (!_isEnabled)
    {
        this.Enabled = true;
        OnEnabled();
    }
}

public void Disable()
{
    VerifyCalledOnUIThread();

    if (_isEnabled)
    {
        this.Enabled = false;
        OnDisabled();
    }
}
protected virtual void OnEnabled()
{
}
protected virtual void OnDisabled()
{
}

When binding UI elements to the DataModel we’ll need some mechanism to enable the DataModel when the element is loaded and disable it when the element is unloaded. There’s an elegant way to implement this behavior which we’ll implement in a future post.

That’s it! We’ve got a basic class to derive out data models from. Note that we’re only addressing one-way data binding for the moment. We’ll address a two-way data model (which requires the ability to commit\rollback data etc.) in future post.

On the next post we’ll look into a concrete DataModel implementation for our Stocky application.

You can download the code for this post from here:

&nbsp;

Further Reading

kick it on DotNetKicks.com

Tags: , , , ,

Developing a Robust Data Driven UI Using WPF - Introduction

.NET, Architecture, Development, WPF March 18th, 2008

WPF, Microsoft’s not-so-new-anymore UI technology offers new capabilities allowing both developers and designers to work together to achieve a stunning experience for their applications.

Power, however, does not come without complexity, and WPF does not provide a framework or a model to solve many of the problems faced by developers and designer when building an application:

1. Handling Rich Data Forms. Many applications, especially when it comes to enterprise applications, rely heavily on displaying and manipulating data. Fetching the data while keeping the UI alive and responsive is a complicated task that’s also hard to debug and requires an experienced developer doing the work.
Can we come up with a framework that will simplify data fetching?

2. Testability is a Requirement for Software Development Framework. Development organizations are no longer satisfied with simple reduction of costs for initial development and there’s a growing demand for frameworks and tool to facilitate a sustainable and agile development process.
Can we come up with a model that will allow writing tests for the application’s UI and behavior?

3. Metadata Driven User-Interface. WPF provides XAML as a meta-model for UI definitions. However there is no clear separation between metadata and code which is a mess when it comes to designer and developers working together.
Can we come up with a model to allow developers provide all the UI logic as closed building blocks that designer can just use in a plug-and-play manner?

Providing a Framework for Building Robust, Data-Driven UIs

The Model\View\Controller (MVC) architectural pattern has long been used by complex applications to present large amount of data to the user.
The pattern allows developers to separate the actual data (Model) from the user interface (View) and the business logic manipulating the data (Controller).

In the following set of articles I will present a variation of the MVC pattern tailored for modern UI development (in WPF) where we’d like the View to be the responsibility of a designer rather than a classic developer writing code.

I’ll be using the DataModel\ViewModel\View terminology to describe the pattern (although you may find the same pattern described using various other terminologies when browsing the net).

Introducing the DataModel\ViewModel\View Pattern

As mentioned earlier, the DataModel\ViewModel\View pattern is a variation of the MVC pattern. Its focus is on making the View, which is the actual UI presented to the user, the responsibility of a designer - a person who is generally more oriented towards graphics, art and interaction than to classic coding.

The design of the view should be done in a declarative form (XAML) using a WYSIWYG tool (Expression Blend).
In short, the actual UI is developed using different tools and languages by a person with a different skills set than business logic and data backend.

In order to understand the meaning behind the DataModel\ViewModel\View terminology lets look at the following diagram describing
typical architecture for our application’s presentation using this pattern:

image

The DataModel

The DataModel is defined exactly as the Model in MVC; it is the data or business logic that stores the state and does processing of the problem domain.
The DataModel abstracts expensive operations such as data fetching without blocking the UI thread. It can keep data “alive” fetching it periodically from source (example: stock ticket), merge information from several sources etc.
The DataModel is completely UI independent and pretty much straightforward to unit test.

The View

The View consists of visual elements and represents the actual user interface presented to the users (buttons, windows, graphics, etc.). It also defines interaction for keyboard shortcuts and other input devices .

The View is defined declaratively in XAML by the designer (usually using a tool such as Expression Blend).
Using such a declarative model makes it to harder to represent some state that the original  View from the MVC pattern was meant to deal with - this includes dealing with multiple modes of interaction (such as “view mode” and “edit mode”) that change the visuals and behavior of the controls.

This is where we make use of WPF’s advanced data binding mechanism. In a simple scenario we can simply bind the View to the DataModel and use binding expressions to perform one-way binding for display only values or two-way binding to allow editing values in the DataModel.

In most scenarios, however, only a small subset of the application’s UI can be bounded directly to the DataModel. This can be the case when the DataModel is a pre-existing class or data schema over which the application developer has no control. The values exposed by the DataModel are likely to require some processing in order to allow binding to UI elements. There may also be several complex operations that require code implementation and do not fit into the strict declarative-only definition for a View but are too application specific to be part of the DataModel (which we might not have control over).
We may also want to save some view state such as view mode (view\edit\etc.) or item selection etc.

To bridge this gap between the declarative View and the DataModel we define the ViewModel…

The ViewModel

The ViewModel bridges between the DataModel and the View and performs all the tasks mentioned in the previous paragraph.
The terms is meant to describe a “Model of a View” which basically means that the ViewModel abstracts all the behavior logic behind a specific screen (View) in the application.
The ViewModel include converters that can transform DataModel types into View types, Commands that can be executed the the View’s control and interact with the DataModel and general behaviors that can be attached to UI elements in the View.

Summary and Next Steps

stockyscreen

The DataModel\ViewModel\View defines a simple yet powerful pattern allowing developers and designers to collaborate on building a robust, data-driver WPF UIs.

It allows separating the data layer from the view layer and the UI to support easier development of granular components that are also unit-testable.

To demonstrate how the various pattern components are developed and used we’ll be going over the development process of a stock ticker widget-like application dubbed Stocky (screenshot on the right) and see how this development pattern simplifies the creation of an otherwise quite complicated little application.

References:

kick it on DotNetKicks.com

Comments (6) from www.ekampf.com/blog/:

Tuesday, March 18, 2008 4:09:58 PM (GMT Standard Time, UTC+00:00)

In my company We developing a very big medical system with UI based on WPF.
We used a combination of the Model-View-Presenter and the DataModel-View-ViewModel introduced by Den Crevier’s.
looking forward to see your implementation.

Ran Trifon

Tuesday, March 18, 2008 4:52:31 PM (GMT Standard Time, UTC+00:00)

Well it’s pretty much the same…
The goal here is to summarize all the information into one place. Dan’s post are pretty short and straightforwards aimed at experienced developers and these post are meant to be more detailed.
I am going to post about topics he didn’t mention though…

Eran Kampf

Tuesday, March 25, 2008 3:41:31 PM (GMT Standard Time, UTC+00:00)

Nice post - I’m really looking forward to seeing where you go with this. I’ve just recently being trying to find some guidance on setting up an MVC/MVP framework in WPF. Dan’s series is great but I must admit that I really didn’t understand it all until I began my own implementation and things began to “gel”. Will be great to see another perspective on it.

Nigel Spencer

Tuesday, March 25, 2008 3:53:55 PM (GMT Standard Time, UTC+00:00)

Thanks Nigel,
Next post in the series is already available at http://www.ekampf.com/blog/2008/03/24/DevelopingARobustDataDrivenUIUsingWPFTheDataModel.aspx

Eran Kampf

Tuesday, March 25, 2008 6:38:44 PM (GMT Standard Time, UTC+00:00)

Eran:
Just wanted to say “keep up the good work”. between your work and Dan’s series of articles, I think I’m starting to get a handle on this. My one request is that I’d like to see how your DataModel interacts with the DataAccess Layer against SQL Server. Maybe just something against Northwind. I realize this might be outside the main scope but I think it would be interesting.
Sincerely,
Dale Williams

Dale Williams

Tuesday, March 25, 2008 7:34:38 PM (GMT Standard Time, UTC+00:00)

Hey Dale,
Thanks for the feedback :)
The 3rd post in the series will show a concrete DataModel example.
Since I was aiming to show how I build a Yahoo finance widget clone I was building the DataModel on that - keeping a stock data up to date (kind of like in Dan’s article).
However, once you see how the DataModel fetching is implemented it doesn’t really matter if the actual data is fetched via SOAP call, http, or a DB access so you’ll be able to implement a one-way binding to a data source of your choice.
While the current implementation only deals with one-way binding (only fetching the data from the without the ability to update data on the source) I do plan to show how to implement two-way binding and support comitting and rolling back data in future posts.
Thanks,
Eran

Eran Kampf

Tags: , , ,

WPF Screen Saver Template for Visual Studio 2008

Development, WPF March 17th, 2008

I wanted to build a screen saver and came across Karen’s template which is made for Visual Studio 2005 and .NET 3.0.
Since I’m on Visual Studio 2008 and .NET 3.5, I took Karen’s template and made some modifications to support it.

So, if you want to create a screen saver with Visual Studio 2008 here’s a template for you:

Installation Instructions

  1. Download the zip file.
  2. Copy the zip (do not extract) to <My Documents>\Visual Studio 2008\My Exported Templates
Technorati Tags:

kick it on DotNetKicks.com

Tags:

Silverlight Goes Mobile

Silverlight, Technology March 4th, 2008

Nokia just announced its intentions on bringing Microsoft’s Silverlight to its mobile phones:

Nokia to bring Microsoft Silverlight powered experiences to millions of mobile users
March 04, 2008

Extends choice for developers on the world’s leading mobile platforms

Espoo, Finland - Nokia today announced plans to make Microsoft Silverlight available for S60 on Symbian OS, the world’s leading smartphone software(1), as well as for Series 40 devices and Nokia Internet tablets.  Adding support for Silverlight will extend opportunities for developers to create rich, interactive applications that run on multiple platforms in a consistent and reliable way.

"Today’s consumers are very clear in what they want: easy access to tightly integrated services and data on any device," said Lee Williams, Senior Vice President in Nokia’s Devices software organization. "Nokia’s software strategy is based on cross-platform development environments, enabling the creation of rich applications across the Nokia device range.  Nokia aims to support market leading and content rich internet application environments and to embrace and encourage open innovation. By working with Microsoft, we are creating terrific opportunities and additional choices for the development community, S60 licensees and the industry as a whole."

Silverlight is a cross-browser, cross-platform plug-in for delivering next-generation media experiences and rich interactive applications.  Silverlight is already powering thousands of applications around the world and organizations including Entertainment Tonight, the NBA and NBC Universal to deliver superior Web-based experiences to their customers.  The arrangement with Nokia will substantially extend the reach of Silverlight by making the platform available for hundreds of millions of devices, including S60 on Symbian smartphones from a range of manufacturers, as well as Nokia Series 40 devices and Nokia Internet tablets.

"This is an important relationship on so many levels. Working with Nokia means we are easily able to reach a huge number of mobile users, including customers of all S60 licensees.  This is a significant step in gaining broad acceptance for Silverlight and ensuring it is platform agnostic. This is critical since we want to make sure developers and designers don’t have to constantly recreate the wheel and build different versions of applications and services for multiple operating systems, browsers and platforms," said S. Somasegar, Senior Vice President of Microsoft’s Developer Division.

"There is clear market demand for rich, Web-based services across a variety of device types, but developing these can often be commercially difficult. For Microsoft this extends Silverlight to a broader range of vendors, platforms and devices.  For Nokia it expands the web runtime options on its devices, enabling a wider community of developers and more applications. This should help the  uptake of higher speed mobile services and advance a new era of anytime, anywhere device-based computing", said Bola Rotibi , Principal Analyst at Ovum.

Microsoft will demonstrate Silverlight on S60 during the opening keynote at Microsoft’s MIX08 conference on March 5 in Las Vegas. Silverlight is intended to be available to S60 developers later this year with initial service delivery anticipated shortly thereafter for all S60 licensees.   This will allow S60 application developers to use an even wider range of development environments for S60 on Symbian OS than today. Today S60 developers can use: C++ (using native Symbian OS APIs and Open C providing subset of standard POSIX libraries), S60 Web Run-time (supporting standards-based web technologies such as Ajax, JavaScript, CSS and HTML), the Java(TM) language, Flash Lite from Adobe, and Python.

I wonder if this is Silverlight 2.0 they’re talking about. Will we have a CoreCLR running on Symbian OS?

Technorati Tags: ,,

Managed Quake 3 Arena

.NET, Development, Game Development January 27th, 2008

Now that’s pretty cool…  A .NET port of the Quake 3 Arena source code.

ManagedQuake3Screenshot

Short Introduction to Powershell

Development, Microsoft January 8th, 2008

I have a short introduction to Powershell presentation at SAP today and to make things interesting I made the presentation slides using a Powershell script rather than using Powerpoint (I actually stole and modified this).

So, here are my presentation’s “slides”:

$ppt = {
cls;
write-host Windows PowerShell in 5 minutes;
write-host *******************************;
Read-Host;
write-host * Next-generation command-line shell;
write-host * Object-oriented;
write-host
Read-Host;
cls;
write-host Discoverability;
write-host ***************;
Read-Host;
write-host * Getting started;
Read-Host;
write-host * Demo - Scream for HELP: get-help;
Read-Host;
powershell;
cls;
write-host Commandlets and aliases;
write-host ***********************;
read-host;
write-host * Cmdlet = Verb + Noun;
read-host;
write-host * get-process, get-childitem, clear-host, …?;
read-host;
write-host * Enter aliases;
Read-Host;
write-host * Demo - get-command and get-alias;
Read-Host;
powershell;
cls;
write-host Object-orientation;
write-host ******************;
read-host;
write-host * Developers, developers, developers?;
read-host;
write-host * NO!;
read-host;
write-host * What is an object?;
write-host   - Data = properties;
write-host   - Operations = methods;
read-host;
write-host * Discoverability: get-member
read-host;
write-host * Demo - Working with system processes - The old way;
write-host;
cmd;
cls;
write-host Object-orientation;
write-host ******************;
write-host;
write-host * Developers, developers, developers?;
write-host;
write-host * NO!;
write-host;
write-host * What is an object?;
write-host   - Data = properties;
write-host   - Operations = methods;
write-host;
write-host * Discoverability: get-member
write-host * Creation: new-object
write-host;
write-host * Demo - Working with system processes - The old way;
write-host;
write-host * Demo - Working with system processes;
Read-Host;
powershell;
cls;
write-host Drives all the way;
write-host ******************;
read-host;
write-host * What is a drive? [a-Z]:;
read-host;
write-host * Much more;
write-host   - HKLM:;
write-host   - Cert:;
write-host   - Variable:;
write-host   - Alias:;
read-host;
write-host * get-psdrive
read-host;
write-host * Demo - Dive into the registry;
Read-Host;
powershell;
cls;
write-host Conclusion;
write-host **********;
read-host;
write-host * 5 commandlets to remember:;
write-host   - get-help;
write-host   - get-command;
write-host   - get-alias;
write-host   - get-member;
write-host   - get-psdrive;
read-host;
cls;
write-host Q “&” A;
write-host *****;
write-host;
write-host * eran@ekampf.com;
write-host * http://www.ekampf.com/blog/;
read-host;
$ie = new-object -Com internetexplorer.application;
$ie.Navigate2(”http://www.ekampf.com/blog/”);
$ie.visible = 1;
exit;
};
&$ppt;

Below are my presentation notes:

Windows Powershell in 5 minutes
——————————-

Powershell is Microsoft next-generation command-line shell.
It’s important to note that it processes objects and not text and we’ll see how later on…

 

Discoverability
—————

Get-Help or help syntax - show how to get commands help

 

Commandlets and aliases
———————–

- Demonstrate Get-Command, Get-Alias (and the other alias functionalities - set, remove)

 

- Object-Orientation -
Explain the Powershell execution pipeline and the fact that it works on objects and not text.
Get-Member is used to get the object properties and methods.

 

The old way:
run tasklist.exe
tasklist.exe gives text output and hard to manipulate

 

The new way:
- Get-Process
- Get-Process | Get-Member
- Get-Process | select name, id
- get-process | where-object {$_.Name -match “^svc*”} | select name, id

 

Powershell can also work with .NET and COM objects:

 

New-Object COM sample:
$ie = new-object -comobject InternetExplorer.Application
$ie.navigate2(”www.microsoft.com”)
$ie.visible = $true

New-Object .NET sample:
$date = New-Object -Type System.DateTime 1982,02,27
$date.get_DayOfWeek()

 

Invoke example:
$script =

  $ie = new-object -comobject InternetExplorer.Application
  $ie.navigate2(”www.microsoft.com”)
  $ie.visible = $true
}
&$script

 

Drives all the way
——————

 

Get-PSDrive - return list of available providers
Providers are Powershell’s way to provide access to data

 

Play with the registry:

cd hklm:\software\Microsoft\
Get-ChildItem
dir
dir | where-object {$_.Name -match “_DeleteMe*” }
New-Item _DeleteMe
dir | where-object {$_.Name -match “_DeleteMe*” }
cd _DeleteMe
New-ItemProperty -Name Test -PropertyType String -Value “bla!”

 

kick it on DotNetKicks.com

Technorati Tags: ,,

Tags:

My Takes From the Silverlight Firestarter Event

Development, Microsoft, Silverlight, WPF December 3rd, 2007

  • Silverlight is pretty cool for doing interactive web apps.
    • I think they concentrated on Video too much on version one and I would have wanted the features in Silverlight 2.0 (WPF controls etc.) in 1.0 and video added later on. Comm’on, how many of us really set on developing another YouTube clone?
    • Leverages developers .NET and WPF knowledge for web apps. This is what I like most about Microsoft’s offering they have one basic platform that requires one set of basic skills which can later be applied to multiple platforms and kinds of applications.
  • I hate the fact Silverlight 1.0 works with JavaScript codebehind.
  • I hate JavaScript…

I think the most interesting session was Adam Kinney’s, who demonstrated the development process of his XBox Live! silverlight gadget. After getting some gamer tags from the audience and realizing that all would probably be offline as they’re in the event, one person had a “1 minute ago”… hmm…

And for other notes, as in any Microsoft event they have giveaways:

  • I missed the Silverlight T-Shirts giveaway at the beginning of the event and when I came to the organizers later they sadly said that they  only have Small size shirts left. If you haven’t shopped for clothes in the US, size Small is pretty much like Large… and they usually don’t have Small… I was expecting an XXL size shirt and got a small which is just my size so I’m happy :)
  • Microsoft Research were giving out cool bags for filling a form. By the time I filled the form they were out of bags and I got a “Microsoft Research” rubber ball :\
  • I almost got a book at one of the lectures
  • As usual, I didn’t win anything at the raffles (I never get lucky in raffles)

When I was leaving the Silverlight event there was some Zune marketing\analysts\team\?? meeting in the next room.
Microsoft are planning a PR effort on Zune for Mother’s day and Christmas focusing on the wifi capabilities which are Zune’s differentiator.

Not convinced. But to be fare, I don’t really like the new iPod video or the shuffle… Nothing like my good old iPod Shuffle.

Technorati Tags: ,,,

Tags: , ,

.NET Web Products Roadmap (ASP.NET, Silverlight, IIS7)

Microsoft, Silverlight, Web 2.0 November 29th, 2007

Scott Guthrie just published a comprehensive post detailing Microsoft’s .NET web products roadmap.
To sum up the release schedule:

  • .NET Framework Source Code - No date specified in the post but should be any time now.
  • ASP.NET 3.5 Extensions - Preview version will be available next week
  • Silverlight 2.0 - Public beta on Q1 2008 (With Go-Live licence)
  • IIS 7 - Will be part of the Windows 2008 release. The official launch is at February 27th 2008 so it’ll probably RTM before that.

I’m extremely happy to see Silverlight maturing as a web development platform with its 2.0 version that includes:

  • WPF UI Framework: The current Silverlight Alpha release only includes basic controls support and a managed API for UI drawing.  The next public Silverlight preview will add support for the higher level features of the WPF UI framework.  These include: the extensible control framework model, layout manager support, two-way data-binding support, and control template and skinning support.  The WPF UI Framework features in Silverlight will be a compatible subset of the WPF UI Framework features in last week’s .NET Framework 3.5 release.
  • Rich Controls: Silverlight will deliver a rich set of controls that make building Rich Internet Applications much easier.  The next Silverlight preview release will add support for core form controls (textbox, checkbox, radiobutton, etc), built-in layout management controls (StackPanel, Grid, etc), common functionality controls (TabControl, Slider, ScrollViewer, ProgressBar, etc) and data manipulation controls (DataGrid, etc).
  • Rich Networking Support: Silverlight will deliver rich networking support.  The next Silverlight preview release will add support for REST, POX, RSS, and WS* communication.  It will also add support for cross domain network access (so that Silverlight clients can access resources and data from any trusted source on the web).
  • Rich Base Class Library Support: Silverlight will include a rich .NET base class library of functionality (collections, IO, generics, threading, globalization, XML, local storage, etc).  The next Silverlight preview release will also add built-in support for LINQ to XML and richer HTML DOM API integration.

When evaluating Silverlight (1.0 and 1.1) a few month ago I came to a conclusion that its not mature enough for us to use it for building business UIs. Having support for only vector graphic shapes meant that any control had to be built manually which means we would have had to manually build a lot of controls ourselves.

With the new support for WPF UI Framework and Rich Controls it now seems more robust for building LOB applications.

Some ideas regarding Silverlight in LOB apps:

  1. Embed Silverlight in InfoPath. InfoPath forms only support a limited set of controls and since its driven by IE it could be extended by embedding ActiveX controls. If you want rich graphics, animations, graphs, etc. as part of your form you have to embed some sort of an ActiveX.
    Of course, you can always develop you’re own ActiveX and embed a WinForm or WPF inside InfoPath but why go through all that work when Microsoft already implemented Silverlight ActivX for you?
  2. Outlook folder Homepage. Folder homepages in Outlook are htmls. To display rich UI in that view the only (hacky) way (presented by Microsoft as part pf project Elixir on MSDN) is to embed an ActiveX in that html and have it connect with an Outlook addin via .NET remoting. Silverlight can be used to save the work and effort on developing (and deploying) your own ActiveX.

I guess we’ll have to re-evaluate Silverlight when the 2.0 beta comes out…

On other notes, I’m at Redmond right now attending the Silverlight 1.0 Firestarter event which should be interesting…

Tags: , , ,

Uninstalling Previous Versions of Visual Studio 2008

.NET, Microsoft November 19th, 2007

Here are the instructions to follow before you install Visual Studio 2008 RTM:

  1. Go to the Control Panel and launch Add/Remove Programs
  2. Remove all instances of Visual Studio 2008/Codename Orcas products
  3. Remove any remaining supporting products in the specified order.
    • Remove “Crystal Reports for Visual Studio 2008 beta2″ (or “Crystal Reports 2007″)
    • Remove “MSDN Library for Visual Studio 2008 Beta”
    • Remove “Microsoft SQL Server Compact Edition 3.5″
    • Remove “Microsoft SQL Server Compact Edition 3.5 Design Tools”
    • Remove “Microsoft SQL Server Compact Edition 3.5 for Devices”
    • Remove “Microsoft Visual Studio Performance Collection Tools”
    • Remove “Windows Mobile 5.0 SDK R2 for Pocket PC”
    • Remove “Windows Mobile 5.0 SDK R2 for Smartphone”
    • Remove “Microsoft Visual Studio Web Authoring Component / Microsoft Web Designer Tools”
    • Remove “Microsoft Visual Studio Tools for Office Runtime 3.0″
    • Remove “Microsoft Device Emulator 3.0″
    • Remove “Microsoft Document Explorer 2008″
    • Remove “Microsoft Visual Studio Codename Orcas Remote Debugger”
    • Remove “Microsoft Visual Studio 64bit Prerequisites Beta” (64-bit platforms only)
    • Remove “Microsoft .NET Framework 3.5″
    • Remove “Microsoft .NET Compact Framework 3.5″

Now that you’re sure all the beta bits are are gone you can install the Visual Studio 2008 RTM edition of your choice…

Note that the list above are the products that were on my machine  and you might have additional products that require removal on your machine.

Update 20/11/2007:

ScottGu just published his own version of the list. When writing this post I started from the same list Scott has now made public but I updated it according to the products that were installed on my machine (removed some stuff, renamed some stuff to fit the name as it appears in beta2). So basically there shouldnt be a difference between the two…

kick it on DotNetKicks.com

Tags: ,

Silverlight 1.0 Fire Starter

Microsoft, Silverlight, Technology, WPF November 8th, 2007

UntitledIn the Seattle area on November 29 and looking for something to do? Why not join a Silverlight workshop at Microsoft Redmond?

On November 29, 2007 Microsoft will be hosting Silverlight 1.0 Fire Starter on the Redmond, Washington campus. This daylong event is free to anyone who wants to learn about designing and developing with Microsoft Silverlight 1.0.

Don’t worry, if you can’t be there in person, I am told we are going to make all the material available on line after the event..

Microsoft Silverlight 1.0 is a cross platform browser plug-in that enables for easy development of media rich web sites.  For more information, visit http://silverlight.net.

November 29, 2007
Microsoft Redmond Campus
1 Microsoft Way
Redmond, WA
Building 33, Kodiak Room
** Please have a photo ID with you to register onsite and park


Check-in:
8:00 am
Event: 8:30 am – 5:00 pm
Register:
http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032359153&Culture=en-US
or by calling 1-877-673-8368 and referencing Event ID 1032359153

Check out the Facebook event page at http://www.facebook.com/event.php?eid=14189895595

I’m definitely going to try and make it…

(via Brad Adams’s blog)

Tags:

HEROES Happen {here}

.NET, Development, Microsoft November 7th, 2007

A new site dedicated to the launch events of Windows 2008, Visual Studio 2008 and SQL Server 2008
has been unveiled at http://www.heroeshappenhere.com/

Currently it contains some videos of Microsoft professional sharing their feelings about the launch but it’ll soon contain some more information regarding the event:

Coming soon this site will provide you the portal for all launch information, event registration, learning resources and new and fun way where you can highlight how technology has made you a Hero. You will be able to experience launch in a whole new way from interactive community tools and forums, new demonstrations and online training options, and even a never before seen surprise from Microsoft which will enable you to experience launch in a new and exciting way. Heroes Happen Here, and make sure you don’t miss out.

I guess I’ll have to stay tuned then…