Web Atoms JS renamed to Atoms.js

On May 4, 2014, in Uncategorized, by Akash Kava

Atoms.js from Web Atoms JS

We are happy to announce, we have redesigned our product name from Web Atoms JS to Atoms.js and we have updated license to MIT License.

Source Code on GitHub

We are also happy to announce moving onto GitHub, we have migrated our source code and relevant documentation on GitHub and we hope to see more contributions from GitHub community.

https://github.com/neurospeech/atoms.js

Documentation Update

We have also hosted all documentation on http://atomsjs.neurospeech.com

Share
 

Migrating from Flex to HTML5 with Web Atoms JS

On September 14, 2013, in Programming, RIA, by Akash Kava

Flex – MXML + ActionScript

Flex was great platform, and it still it is, we spend years developing on flex and MXML markup was probably the best way to write UI components. However, dependency on Flash forced us to move away from Flex and migrate to HTML5.

HTML as Universal UI Language

  • Each device has different UI Elements and Different way of Interaction
  • Each device has different scale and screen measurement
  • Each device needs different programming language expertise
  • Each device has its own set of APIs
  • Emerge of Unified HTML Device Programming like PhoneGap
  • UI is complex to write, and is even more complex to rewrite for different platforms
  • Web is truly a unified version of User Interface

Problem with JavaScript

  • Easy to write
  • Difficult to maintain
  • Difficult to Refractor
  • Difficult to understand our own code
  • Cannot blame anyone for my own code
  • Difficult to visualize UI Hierarchy
  • How does my UI Looks?
  • And this is what code looks at the

Backbone, jQuery, Knockout, Prototype ….. Endless Names with Endless Forks on Github

No doubt, each of frameworks are trying to deliver Flex kind of capabilities, but not at all close enough. Creating application with any of them requires huge knowledge of JavaScript itself, including no inbuilt object oriented support. But code becomes chunky, JavaScripting is tedious. A year and half back, we studied and implemented every JavaScript frameworks, but it resulted in huge learning curve for people coming from Flex/Silverlight and Java background. All these libraries are based on “Functional Programming” where else Flex/Silverlight and JavaScript are based on component driven development.

Reason behind Web Atoms JS

Primary focus of Web Atoms JS was to introduce and emulate component driven development found in Flex/Silverlight and Java. A true potential of Object Oriented Development along with simpler syntax without reinventing whole new language. Let’s analyze small Flex Code vs Small Web Atoms JS code. A simple Signup Form.


Now let’s review, Web Atoms JS example for exact same UI component.


If you notice, methodology is exactly same, however since HTML does not offer custom Tag Names, we have to use atom-type attribute to convert HTML element to Web Atoms UI Element. For Flex/Java and Silverlight developers, this syntax is easier to grasp and learn instead of New HTML Grammar Syntax which is confusing. So let’s review available Flex to HTML components already shipped with Web Atoms JS version 1.1.1.

Web Atoms JS Counter Part Flex
AtomViewStack View Stack
AtomFormLayout Form
AtomFormGridLayout – a dynamic Form Layout that can manage multi column rows, with each row having independent number of columns.
AtomForm, AtomPostButton with AtomPromise. AtomPromise encapsulates all AJAX calls and AtomPromise is tightly integrated into Property System, so you can assign a promise and async call is automatically managed. HttpService
AtomListBox List
AtomItemsControl Repeater
AtomToggleButtonBar Horizontal List
AtomDockPanel Grid
Item Template Item Renderer
AtomWindow Panel
AtomFileUpload – AJAX File Upload
AtomVideoPlayer VideoDisplay
AtomNavigatorList – iPhone kind of UI Navigator to drill into detail and coming back Mobile Views ?

 

Dynamic Compilation from Flex to JS vs Recreating Components

We earlier did wait from Adobe to bring some sort of AS to JS compiler, but we realize that HTML5 is coming up with new technologies. Any dynamic compilation from Flex to JS will not result in perfect HTML app as Flex does not contain HTML elements and there is no possibility of including more HTML library. CSS3 brings up lots of new things and HTML will come with new things, it will not be easy to incorporate anything else apart from Flex components. So one time migration from Flex to HTML5 will give us the freedom from Flex itself as well as we will be able to expand and integrate other HTML or JS libraries easily.

Learning Curve

In case of Web Atoms JS, it is just a syntax that is different, but most common logic remains same, as Web Atoms JS comes with Components that are already used by your developers and they are familiar with all of them. Component properties are also very much similar to that of found in Flex/Silverlight and Java.

Mobile Development

All of components shipped in Web Atoms JS are 100% mobile browser compatible infact they are compatible with even non mobile devices like TV, Camera etc.

Single Framework

Web Atoms JS provides almost everything that you need to create working business application. However we have not considered Graphs yet, but there is an easy way to integrate third party components as well.

Editing Support

We have provided rich syntax highlighter for Visual Studio as of now, and we will be coming up with more editor supports soon. You can also check out our live website and you will get CodeMirror extension to colorize Web Atoms attributes on HTML.

Debugging Support

To analyze inherited Data properties and other Scope properties, we have created Chrome Web Atoms Properties Pane extension, which lets you analyze HTML Elements and data associated with it.

Download Source and Documentation

http://webatomsjs.neurospeech.com/resources/web-atoms-1.1.1.zip

Share
Tagged with:  

Here comes just another JavaScript framework, well new complicated syntax, lots of new methods and lots of complex JavaScript files to manage? Certainly not, pain of JavaScript is real, and it is also the only option.

Mission of Web Atoms

  1. Not to Invent a New Language
  2. Use more Markup and Less Code (Less Script)
  3. Component Driven Development to increase reusability
  4. Help Existing Apache Flex developers to migrate to HTML5
  5. Integrate Features of Flex and Silverlight into JavaScript

Features

  • Declarative UI Bindings
  • Automatic UI Refresh (One way and Two way Binding)
  • Template Engine
  • Ready to use Business Controls
  • Command Chaining (Advanced MVC)
  • Private Scope Isolation for Components
  • Most Simple form of AJAX Ever (AtomPromise)

Simple Example

<div
    atom-type="AtomListBox"
    atom-items="{ AtomPromise.json('movie-list.json') }"
    atom-name="movieList"
    atom-auto-select-on-click="{ false }"
    atom-allow-multiple-selection="true"
    atom-value-path="MovieName"
    >
    <table>
        <thead>
            <tr>
                <th>
                    <input
                        type="checkbox"
                        atom-type="AtomCheckBox"
                        atom-is-checked="$[scope.movieList.selectAll]"/>
                </th>
                <th>
                    Movie
                </th>
                <th>
                    Category
                </th>
            </tr>
        </thead>
        <tbody
            atom-presenter="itemsPresenter">
            <tr atom-template="itemTemplate">
                <td><input type="checkbox" atom-type="AtomItemSelector"/></td>
                <td atom-text="{ $data.MovieName }"></td>
                <td atom-text="{ $data.MovieCategory }"></td>
            </tr>
        </tbody>
    </table>
</div>

The above code contains a List Box with set of attributes that customizes its behavior. The above sample fetches list of countries from given URL, and then it displays in the table format. Child element of List Box element is template which defines visual layout of List Box. Web Atoms evaluates expressions with $ sign and performs UI Data Binding against those items.

Binding Convention

  • A valid JavaScript Expression between curly braces {} is considered as One Time Binding and it is evaluated only once during initialization of component/element or control.
  • A valid JavaScript Expression between square brackets [] is considered as One Way Binding (UI refreshes when target data changes) and $ determines beginning of source of change.
  • A property path between square brackets [] prefixed with $ is considered as Two way binding in which Data Source is updated as well in response to user interaction.

Scope Isolation

Scope is an object store associated with UI Component or UI Control referred as AtomControl, which provides an isolated storage as per its position in UI Hierarchy. Every UI Control in Web Atoms has a property with name scope, appScope and localScope. Each property gives you access to scopes available at current Scope, Global Application Scope (Global Scope for every component to share data) and a private Local Scope. Scope and Global Scope are maintained by Web Atoms and developers can not control them, however developers can create Local Scope and every children is now part of new Local Scope and is isolated from other Scope.
By giving Name to UI Control, control and its properties become accessible through the scope.
Scope also lets you put functions in it, and different scopes never interfere with same named items. By convention, Scope initialization is written differently than conventional JavaScript.

<script type="text/javascript">
    ({
        view: 'red',
        list: [
            { label: 'Oranges', value: 'orange' },
            { label: 'Apples', value: 'red' },
            { label: 'Grapes', value: 'green' }
        ],
        display: function (item) {
            if (!item)
                return '';
            return item.label + ' are ' + item.value;
        }
    })
</script>

The above script is actually an harmless code, which does nothing when it is parsed and executed by browser. However, the library removes this script and stores it for execution on later stage. And when the controls are initialized, Web Atoms will setup scope corresponding to its position in UI Hierarchy. After setup, these values are available as $scope.view, $scope.list and $scope.display respectively. By accessing through scope property, it provides isolation needed for multi component hosting on one page.

 

Following sample illustrates use of local scope.

    <div
        atom-type="AtomControl"
        atom-local-scope="true"
        atom-abs-pos="100,100,500,200"
        >

        <script type="text/javascript">
            ({
                name: "Scope 1",
                run: function (scope, sender) {
                    alert("Called in Control with " + scope.name);
                }
            })
        </script>

        <button
            atom-event-click="{$localScope.run}"
            >Execute <span atom-text="{$localScope.name}"></span></button>

    </div>

    <div
        atom-type="AtomControl"
        atom-local-scope="true"
        atom-abs-pos="600,100,500,200"
        >

        <script type="text/javascript">
            ({
                name: "Scope 2",
                run: function (scope, sender) {
                    alert("Called in Control with " + scope.name);
                }
            })
        </script>

        <button
            atom-event-click="{$localScope.run}"
            >Execute <span atom-text="{$localScope.name}"></span></button>

    </div>

Simple AJAX (AtomPromise)

In order to provide simple interface to JavaScript promises to implement AJAX and similar asynchronous functionality, Web Atoms has incorporated AtomPromise in the property system, which lets us assign promise in simple expression, but it will do the complex event wiring automatically. In following example, you can see that we are assigning a JSON promise, and it looks like data from url is fetched and assigned to Combo Box. But in reality, we are only assigning a promise, and only if the result of promise will be successful, than actual items from the promise will be assigned in future.

The following example is pretty self explanatory that we are loading list of countries from the given url ‘country-list.json’

<select
    atom-name="countryCombo"
    atom-type="AtomComboBox"
    atom-items="{ AtomPromise.json('country-list.json')}"
    atom-value="$[scope.view]"
    >
</select>

<span
    atom-text="['Selected Country Code is ' + $scope.countryCombo.value]" >
</span>

Templates

In order to achieve true separation of Data and UI, Web Atoms comes with simple DOM Node Templates, which uses UI Data Binding to display contents. And various controls define various templates that can be easily customized by changing Style and other properties of HTML Element. By simply applying an element with atom-template attribute, element is removed from UI Hierarchy and used as template to display the data.

<div
    atom-type="AtomListBox"
    atom-items="{ AtomPromise.json('movie-list.json') }"
    atom-name="movieList"
    atom-auto-select-on-click="{ false }"
    >
    <div
        atom-template="itemTemplate">
        <button atom-type="AtomItemSelector">Select</button>
        <span atom-text="{ ($scope.item_index + 1) + ') ' }"></span>
        <span atom-text="{ $data.MovieName }"></span>
    </div>
</div>

Style Binding

Web Atoms provides extended mechanism of defining and binding individual style properties, which increases granularity of markup.

<script type="text/javascript">
    ({
        list: [
            { label: 'Orange', itemColor: 'orange', itemWidth: 100 },
            { label: 'Apple', itemColor: 'red', itemWidth: 200 }
        ]
    })
</script>

<div
    atom-type="AtomItemsControl"
    atom-items="{ $scope.list }"
    >
    <div
        atom-template="itemTemplate"
        atom-text="{$data.label}"
        style-color="#000000"
        style-background-color="{$data.itemColor}"
        style-width="{ $data.itemWidth + 'px' }"
        >
    </div>
</div>

Style binding is useful when your style is available in the form of Data. Assuming in above example, list is populated from Data.

Licensing

Web Atoms JS is licensed in the following types, please note, license is applicable to the page of the site which uses Web Atoms JS Library.

  1. Free – Attributed License – Commercial or Non Commercial – Requires a back link in bottom right corner of every page to http://webatomsjs.neurospeech.com and Requires Registration with Our Site Directory.
  2. Non Commercial – Open Source Projects – Any open source free apps built and distributed under GPL, BSD, Apache or MIT license can use Web Atoms – Requires Registration with Our Site Directory.
  3. Yearly Subscription – Site License – Single Domain that can be hosted on any number of servers with yearly subscription of $99/year.
  4. Yearly Subscription – Server License – Single Server that can hosted any number of Sites with yearly subscription of $299/year.
  5. Site Perpetual License
    • $999 per Site for hosting on One Server
    • $1999 per Site for hosting on 10 Load Balancer Server
    • $4999 per Site to host on unlimited number of servers or CDN
  6. Server Perpetual License
    • $1999 per Server to host 10 Sites
    • $4999 per Server to host unlimited sites
    • $9999 Data Center License to host unlimited sites on unlimited servers

Documentation

To learn and explore Web Atoms in detail, please visit http://neurospeech.com/webatoms/docs

Share
Tagged with:  

Entity Atoms Flex Edition released

On April 10, 2012, in C#, Programming, RIA, by Akash Kava

We are happy to announce release of Entity Atoms Flex Edition, which provides client frameworks and tools for ASP.NET MVC and RIA Services to access Entity Framework on any mobile platforms.

Microsoft’s latest Entity Framework makes it very easy to setup complex transactional applications. However in order to extend Change Set, Authorization and Audit controls to all mobile platforms Entity Atoms was designed.

Currently, only Flex Edition is available for download, Flex Edition lets you create Flex Mobile application that can execute on any mobile platform.

We are going to release new native framework and tools for major mobile platforms very soon.

Key Highlights

  • Extend Entity Framework to all platforms using RIA Services
  • Simple LINQ Expression Rules to enable Security
  • Enable Table Audits/History including Cascade Delete
  • Customizable Code Generator (Flex, Android, C#, VB.net)
  • Simple Client and Server side validations
  • Easy Access to related entities (navigation properties)
  • JSON Endpoint with Date Handling
  • Additional UI Elements for Flex Mobile
  • Advanced Search (Search navigation properties)
  • Full ChangeSet management at Client Side
  • Unit Of Work pattern at Client Side

System Requirements

  • Windows 7, Windows Vista Service Pack 2,Windows XP Professional.
  • Microsoft .NET Framework 4.0 and above.
  • Microsoft Visual Studio 2010
  • Flash Builder 4.6
  • MS SQL Express 2005 onwards or MySQL or Oracle

Click here to Download Free Demo

Share
Tagged with:  

Windows 8 Developer Preview (First Look)

On September 18, 2011, in Programming, Technology, by Akash Kava

I installed Windows Developer Preview of upcoming operating system Windows 8, and it has few good and bad things. Just like a new product, it has new dashboard and cool way to navigate between apps using touch gesture, these things sure excites me up but also looking at the internals, there are more challenges for everyone to catch up with Window 8.

New Task Manager

Nice of all, I like the new improved Task Manager, which lets me look into complete Process Tree as well as I can see user wise Process Tree.

WindowsTaskManager

It also displays Process Tree grouped by Users.

UserProcesses

And best of all, it lets me control my startup items from here, I can disable items I don’t want to auto start.

StartupItems

New File Copy Dialog

Another improved user interface is, File Copy dialog, instead of old style animation, it now displays a graph of progress with real cool line graph that’s very live.

FileCopyDialog

New Search

Search is redesigned completely and you can search for settings by pressing Window + W key. Let’s say I want to change my desktop background, so I pressed Window + W and I typed “wallpaper”, it did give me these options.

Well I just tried all combinations of Window keys and only found following five useful combinations.

  1. Window + W lets you search the settings (usually control panel)
  2. Window + P lets you switch between dual desktop and connect to projector settings
  3. Window + D brings back the desktop
  4. Window + F lets you search the files
  5. Window + Q lets you search Metro App’s Items

To a big disappointment, I did not find anything to search apps, so I have to click on Windows + W and then click on App to actually search applications installed on my machine.

Wallpaper

No Old Apps on Metro Desktop

Metro UI Apps are redesigned using HTML5+JS and Appx with Windows Runtime (XAML + Windows Runtime). So none of your old Win32, .NET apps will execute on Metro UI. They can only execute inside the desktop (old fashion windows). So we have to redesign and rewrite the applications for Metro Desktop completely from scratch.

Metro Desktop Apps are not Silverlight

Although they quite look like silverlight, but looking at the documentation, Microsoft has introduced complete new set of library with “Windows.UI” namespace, which represents complete copy of Silverlight controls (and more) but they are not silverlight. So if you wrote your apps in Silverlight, they wont directly run on Metro UI, but you might be able to port them to Metro UI with some code changes as namespace changes System.Windows.Controls to Windows.UI.Controls. However, it may not be so easy but you will get very unexpected behavior if you try to port it directly.

Three Different UI Technologies to Deal With

Well the only sad part is, now we have total 3 different UI technologies to deal with.

  1. WPF 3.0, 3.5, 4.0 (Original WPF based on XAML). Apps written on WPF are old fashioned, and they will not execute on Metro UI, they will only run in Desktop version.
  2. Silverlight (Web and Phone), Once again, two different forms of same Silverlight for web and phone. However all web that runs Silverlight (and even flash) wont run on Metro UI.
  3. Windows Runtime (XAML,HTML5+JS), this is complete new set of library including various controls from Silverlight and WPF, however it is still not complete with both of them and it also includes more controls of its own. This is purely for Metro UI. HTML5 and JS are once again little different as Microsoft has its own API embedded to make developers feel easy to write code. But this does not mean that your HTML5 code will work absolutely correctly without any changes on Metro UI. In IE 10, it may run, but to make it an appx, you might need to change few things.

As new UI stack is introduced by Microsoft, we will soon release a new version of “UI Atoms” that will allow users to write Windows Runtime Metro UI apps with UI Atoms Controls.

Share
Tagged with:  

Captcha – What do you really see?

On May 14, 2011, in Programming, by Akash Kava

I was trying to login to my Windows Live account and I may have mistyped my password but next screen locked me out for nearly 4 times asking me more and more difficult captchas.

What-Do-You-See-Captcha

What is Captcha?

Well there are some dirty people who write automated programs to login to website and steal data, so website owners needed something to identify the user as Human or Program. And they made Captcha, a real painful way to prove that I am a human.

Captcha Implemented wrongly on Windows Live

Now I have no way to know whether the password I typed was wrong or the captcha went wrong? Because the error message says,

Type your password and characters in the picture correctly.

So even after nearly 4th effort I posted this blog, because I have no idea what is this. I can figure out first character is probably X or it is a and e. Second character could be anything, A or n or even U for that matter.

Image Captcha is bad

I feel Image Captcha is very bad, I hear from senior citizens that they just cant read and cant understand what is it.

Bad Captcha Implementations

 

Windows Live

Great, just after my experience with Captcha, I posted this blog, that my second attempt of entering password got me feel guilty and I was presented to certify myself as a human.

StackOverflow

It is website where we ask and answer questions, always if I have answered and I may have realized spelling or semantic mistake and I go back to edit it quickly, this website turns on me thinking I am an evil computer program and posts me back a CAPTCHA thinking that it is very rare for a human to click and edit and correct spelling or words within 10 seconds.

I want to add more painful captcha implementations in this post so guys help me adding your own experiences.

Share
Tagged with:  

MEF vs. Unity in composite application (Prism)

On April 27, 2011, in C#, Programming, by Akash Kava

This article describes differences between MEF and Unity which may help you in deciding which technology you must use while making composite application.

Both technologies are useful and easy to understand, and offer a rich set of features that can make integration of various software components very easy. However, both being little different in functioning they offer exact same level of features but choosing wrong one can lead to chaos.

So we will drill down to differences between their operations.

Unity

MEF

Unity creates new instance of type by default.

MEF creates singleton instance of type by default.

Unity does not require registration for classes. This means you can instantiate any other third party type.

MEF requires Export attribute to be specified on the class. MEF cannot create instance of third party type unless it defines Export.

Unity requires type registration in code for interface types.

No registration, simple Export attribute does it all.

Unity container can compose IUnityContainer property in the composed class where you can further access it easily in your own scope. This behavior is not useful for Plugin architecture as getting access to IUnityContainer may result in full access to your application.

MEF does not allow composition of CompositionContainer, which blocks access to MEF in your own scope if you do not have CompositionContainer. This is useful in Plugin architecture where third party code has limited access to your application. 

Unity offers injection method mechanism, that can define IUnityContainer parameter and get the unity container object, with which you can compose other private properties manually.

MEF can only compose public properties, this is dangerous as anyone can change public property and make application crash easily.

Inside your application’s framework code, Unity serves the best as it gives you full control over type hierarchy, lifecycle and allows you to utilize third party components easily without writing much of code. 

Inside your application, MEF will put lots of restrictions in which your framework can operate as it cannot easily compose third party components and it will force you to write numerous attributes in your code without which it will fail drastically.

Mostly, User Interface objects like your View, or UserControl or any UIElement can never be shared as no UIElement can have two parents at same time. So default behavior of Unity to create a new instance of type is very helpful.

Default behavior of MEF will create only one single instance of UI object, that will lead to trouble, not only that, if UI object is third party tool, MEF will not compose it. You can create multiple copies of exported type by specifying one more attribute called [PartCreationPolicy(Shared)], however it is very time comsuming and tedious to define this one every UI related type we create.

Unity does allow singleton objects, but for that you have to register an instance to the container.

MEF by default creates singleton object only.

Unity does not allow multiple registrations for same instance in same scope sharing same interface but different type.

MEF allows multiple singleton objects of different type sharing same interface.

Unity works best for MVVM, as composing user interface parts can be very easy with unity.

MEF does not work great with MVVM as it will create singleton objects that will behave strangely in runtime and lead to UI failure.

Unity is not good for Modularity, as composing IUnityContainer will offer more control of unity lifecycle to third party modules.

MEF is good for Modularity, as it will not allow modification of composition thus offering great deal of security between modules.

So, to develop a framework, MVVM Crud application and a UI framework, Unity is the best.

To expose some functionality of your application for third party modules to register and access limited functionality, MEF is the best.

 
 

Following is outline of how your application should be,

Unity Container must compose and manage your application’s framework, UI and MEF modules.

MEF will only expose limited functionality from Unity Container to third party modules.

No module, through MEF should have access to unity container at all.

Thank you for reading this article, please put your suggestions below in the comment. I do not intend to make any specific rules and regulations here but I am suggesting the architecture based on the differences I have outlined.

Share
Tagged with:  

UI Atoms 1.7.5 Released

On April 3, 2011, in C#, Programming, RIA, Technology, by Akash Kava

We are happy to announce new release of UI Atoms 1.7.5 with following new features.

  1. New AtomDataForm Control
  2. Tabs in AtomForm and AtomDataForm
  3. Lambda Binding Extensions

Introducing new Control AtomDataForm

AtomForm did support UI Validations, however Microsoft RIA Services Client has some inbuilt validation and support for IEditableObject. So we created a new AtomDataForm that supports RIA Services validation and IEditableObject support.

  1. AtomDataForm supports object with IEditableObject interface and fires event for BeginEdit, CancelEdit and EndEdit
  2. AtomDataForm displays items in read only mode unless Edit button is clicked
  3. After edit button is clicked, Save and Cancel button appear for you to persist changes or cancel changes
  4. AtomDataForm contains UI Element (TextBox, ComboBox etc) as children, so you can easily define child ui element in your xaml as shown in sample below
  5. AtomDataForm supports Tabbed layout, for that you can insert your items within AtomDataFormTab as shown in example below
  6. Following sample illustrates Tabs, but you can also create simple user interface without tab as well
  7. You can also use AtomDataFormGroup to group items in to a headered group
  8. Every child element of AtomDataForm can be accessed in code behind file easily because they appear as a variables when you define x:Name property
  9. AtomDataForm supports CanChangeDataContext property, which is false when the form is in edit mode
  10. You can easily reuse any third party control within AtomDataForm, AtomDataFormGroup and AtomDataFormTab
AtomDataForm Sample
  1. <ns:AtomDataForm
  2.     Grid.Column="1"
  3.     DataContext="{Binding SelectedItem,ElementName=dataGrid}" >
  4.             
  5.     <!– 1st Tab–>
  6.     <ns:AtomDataFormTab Header="Default">
  7.                 
  8.         <TextBox
  9.             ns:AtomDataForm.Label="Name:"
  10.             Text="{Binding ProductName, Mode=TwoWay}"/>
  11.                 
  12.         <ns:AtomToggleButtonBar
  13.             ns:AtomDataForm.Label="Type:"
  14.             SelectedItem="{Binding ProductType,Mode=TwoWay}">
  15.             <sys:String>Product</sys:String>
  16.             <sys:String>Service</sys:String>
  17.         </ns:AtomToggleButtonBar>
  18.                 
  19.         <TextBox
  20.             ns:AtomDataForm.Label="Folder:">
  21.             <ns:AtomDataForm.CommandBox>
  22.                 <Button Content="…"/>
  23.             </ns:AtomDataForm.CommandBox>
  24.         </TextBox>
  25.                 
  26.     </ns:AtomDataFormTab>
  27.             
  28.     <!– 2nd Tab–>
  29.     <ns:AtomDataFormTab Header="General">
  30.                 
  31.         <TextBox
  32.             ns:AtomDataForm.Label="Email:"  
  33.             Text="{Binding Email, Mode=TwoWay}"/>
  34.                 
  35.     </ns:AtomDataFormTab>
  36.             
  37.     <!– 3rd Conditional Tab–>
  38.     <!– This tab will be visible only if Product's
  39.     IsTypeService is true–>
  40.     <ns:AtomDataFormTab
  41.         Header="Service"
  42.         IsEnabled="{Binding IsTypeService}">
  43.                 
  44.         <TextBox
  45.             ns:AtomDataForm.Label="Service Details:"/>
  46.                 
  47.     </ns:AtomDataFormTab>
  48.  
  49.     <!– 4th Conditional Tab–>
  50.     <!– This tab will be visible only if Product's
  51.     IsTypeProduct is true–>
  52.     <ns:AtomDataFormTab
  53.         Header="Product"
  54.         IsEnabled="{Binding IsTypeProduct}">
  55.                 
  56.         <TextBox ns:AtomDataForm.Label="Product Details:" >
  57.             <ns:AtomDataForm.CommandBox>
  58.                 <Button Content="Search"/>
  59.             </ns:AtomDataForm.CommandBox>
  60.         </TextBox>
  61.                 
  62.     </ns:AtomDataFormTab>
  63.             
  64. </ns:AtomDataForm>

In above sample you can notice following things,

  1. Header property of AtomDataFormTab is displayed in the title section on the top
  2. AtomDataFormTab contains children and each child can have properties as below
    1. ns:AtomDataForm.Label displays label on left side
    2. ns:AtomDataForm.Description displays description on bottom
    3. ns:AtomDataForm.Title displays title on the top of control
    4. ns:AtomDataForm.CommandBox displays a UI Element on the right corner, usually a search button or expand button
  3. AtomDataFormTab supports IsEnabled binding, you can bind this property to show/hide the tab as shown in the example above
  4. Every child elemen of either AtomDataForm , AtomDataFormTab or AtomDataFormGroup supports Visibility and IsEnabled binding
    1. If Visibility is bound and it results in Collapsed then entire form item is not displayed
    2. IsEnabled binding can enable/disable the editable control

Following is screenshot of Tabbed AtomDataForm in edit mode

AtomDataForm

Introducing Lambda Binder Extensions

Writing binding expressions with conditions and converters can be very complex especially rewriting many and same logic at different classes. Now UI Atoms support, Lambda Binding Extensions which lets you do binding within the code without creating any complex IValueConverter implementation.

Bind Method Extension

Element Property Binding
  1. theForm.Bind(AtomDataForm.HeaderProperty,
  2.     () => string.Format("{0} ({1})",
  3.             productName.Text,
  4.             typeToggleButtonBar.SelectedItem
  5.         ));

This will bind theForm’s Header property to an expression that will combine properties of two different elements. And this will also automatically update when any of bound source or its property will change.

DataContext Property Binding
  1. theForm.Bind(AtomDataForm.HeaderProperty,
  2.     () => string.Format("{0} ({1})",
  3.             theForm.DataContext.Property("ProductName"),
  4.             theForm.DataContext.Property("ProductType")
  5.         ));

Assuming, we may not have property information at design time, but we know that DataContext will be set to an object containing properties, then we can write Property extension method as shown above.

BindVisibility Method Extension

Visibility converters are very frequent so we created a BindVisibility extension method that will let you specify a boolean expression that will be converted to Visibility on the fly.

BindVisibility Extension
  1. productTab.BindVisibility(
  2.     () =>
  3.         typeToggleButtonBar.SelectedIndex == 0);

These extensions can be used anywhere in any third party controls as well.

Download Now

Click here to download your free demo copy of NeuroSpeech UI Atoms 1.7.5

Share
Tagged with:  

Lambda Binder for WPF and Silverlight

On March 20, 2011, in C#, Technology, by Akash Kava

LambdaBinder class helps in creating complex binding expressions without having to create IValueConverter and IMultiValueConverter, it lets you write inline expresions with advanced binding scenarios.

Lets say, you have two TextBox for first and last name and you want a Title to be displayed as addition of both.

So lets say, you can write it as follow,

Adding Two Properties
title.Bind(TextBlock.TextProperty,
    () => firstName.Text + " " + lastName.Text);

Formatting Properties
title.Bind(TextBlock.TextProperty,
    () => string.Format("{0} {1}",
        firstName.Text, lastName.Text));

You can pass on the Linq expression to Bind extension method of LamdaBinder and that will convert and set binding so that anytime if firstName or lastName is modified, the title will be updated automatically.

Assuming I want some hypothetical visibility logic, for example, only if the firstName is entered, lastName should be visible.

Conditional Visibility Binding
lastName.Bind(TextBox.VisibilityProperty,
    () => firstName.Text.Length > 0 ? Visibility.Visible :
        Visibility.Collapsed);

You can also use this to avoid writing IValueConverters and do inline binding in code very easily.

Lambda Binder
public static class LambdaBinder
{

    public static void Bind(
        this DependencyObject dest,
        DependencyProperty destProperty,
        Expression<Func<object>> func)
    {
        MultiBinding b = new MultiBinding();
        b.Converter = new MultiDelegateConverter(func.Compile());
        LambdaBindingBuilder bb = new LambdaBindingBuilder(b);
        bb.Visit(func.Body);
        BindingOperations.SetBinding(dest, destProperty, b);
    }

}

public class LambdaBindingBuilder : ExpressionVisitor
{
    private MultiBinding multiBinding;

    private string lastPath = null;

    public LambdaBindingBuilder(MultiBinding mb)
    {
        this.multiBinding = mb;
    }

    protected override System.Linq.Expressions.Expression VisitMember(MemberExpression node)
    {
        PropertyInfo p = node.Member as PropertyInfo;
        if (p != null) {
            if (string.IsNullOrWhiteSpace(lastPath))
            {
                lastPath = p.Name;
            }
            else {
                lastPath = p.Name + "." + lastPath;
            }
        }
        FieldInfo f = node.Member as FieldInfo;
        if (f != null) {
            Binding b = new Binding(lastPath);
            b.Source = System.Linq.Expressions.Expression.Lambda<Func<object>>(node).Compile()();
            multiBinding.Bindings.Add(b);
            lastPath = null;
        }
        return base.VisitMember(node);
    }

    protected override System.Linq.Expressions.Expression VisitConstant(ConstantExpression node)
    {
        if (!string.IsNullOrWhiteSpace(lastPath)) {
            Binding b = new Binding(lastPath);
            b.Source = node.Value;
            multiBinding.Bindings.Add(b);
            lastPath = null;
        }
        return base.VisitConstant(node);
    }
}

public class MultiDelegateConverter : IMultiValueConverter
{
    private Func<object> func;

    public MultiDelegateConverter(Func<object> func)
    {
        this.func = func;
    }

    public object Convert(object[] values,
        Type targetType,
        object parameter,
        System.Globalization.CultureInfo culture)
    {
        return func();
    }

    public object[] ConvertBack(object value,
        Type[] targetTypes,
        object parameter,
        System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

 

LambdaBinder is part of UI Atoms suite. At NeuroSpeech, we do research on UI and we are coming up with more interesting featues in UI Atoms.

Please Click Here to download latest update of UI Atoms with AtomForm including Tabs in the form.

Share
Tagged with:  

Entity Framework and RIA Services do not allow Entities to be added/removed from cross containers. In order to move Entity from one DomainContext/ObjectContext to another DomainContext/ObjectContext, we need to recursively detach the object graph and attach it to other DomainContext/ObjectContext.

Object Graph

Single entity can be easily detached and attached from EntitySet where it belongs, but the problem comes when navigation properties of entity are not empty. Entity object along with navigation properties is called Object Graph because if you notice, navigation property’s navigation property will contain reference to same entity and that will result in endless recursive code for Detach/Attach.

An entity with the same identity already exists in the EntitySet

When you try to detach entity from old DomainContext/ObjectContext and attach it to DomainContext/ObjectContext, it may give you an error that entity with same identity already exists and it will throw an exception. In this case we will just simply reuse the existing entity instead of attaching the entity we have.

Entity cannot be attached to this EntityContainer because it is already attached to another EntityContainer

In case of ObjectGraph, your root level entity is already detached, but navigation properties are not detached, and while you try to attach your root level entity, it will throw same error for entities that exist in navigation properties.  Because detach method does not recursively detach every entity from navigation properties.

Attach/Detach Extension Methods

Finally after brainstorming little, I made following class that will allow you to recursively detach/attach object graphs from DomainContext. You can replace DomainContext to ObjectContext to use it inside Entity Framework.

DomainContext Extensions
  1. /// <summary>
  2. /// DomainContext Extensions
  3. /// </summary>
  4. public static class DomainContextExtensions {
  5.  
  6.     /// <summary>
  7.     /// Recursively Attaches entity loaded from Other DomainContext to
  8.     /// current specified DomainContext
  9.     /// </summary>
  10.     /// <param name="context">DomainContext where entity will be attached</param>
  11.     /// <param name="entity">Entity loaded from other DomainContext</param>
  12.     /// <returns></returns>
  13.     public static Entity Attach(this DomainContext context, Entity entity)
  14.     {
  15.         if (entity == null || entity.EntityState != EntityState.Detached)
  16.             return entity;
  17.  
  18.         Entity newEntity = entity;
  19.  
  20.         Entity[] list = new Entity[] { entity };
  21.         foreach (Entity c in context.EntityContainer.LoadEntities(list,
  22.             LoadBehavior.MergeIntoCurrent))
  23.         {
  24.             newEntity = c;
  25.             break;
  26.         }
  27.  
  28.         // recursively attach all entities..
  29.         Type entityType = typeof(Entity);
  30.  
  31.         // get all navigation properties…
  32.         Type type = entity.GetType();
  33.         foreach (var item in type.GetProperties())
  34.         {
  35.             if (entityType.IsAssignableFrom(item.PropertyType))
  36.             {
  37.                 Entity navEntity = Attach(context, item.GetValue(entity, null)
  38.                     as Entity);
  39.                 item.SetValue(newEntity,navEntity, null);
  40.                 continue;
  41.             }
  42.             if (item.PropertyType.Name.StartsWith("EntityCollection"))
  43.             {
  44.                 IEnumerable coll = item.GetValue(entity, null) as IEnumerable;
  45.                 List<Entity> newList = new List<Entity>();
  46.                 foreach (Entity child in coll)
  47.                 {
  48.                     newList.Add(Attach(context, child));
  49.                 }
  50.                 dynamic dcoll = item.GetValue(newEntity,null);
  51.                 foreach (dynamic child in newList)
  52.                 {
  53.                     dcoll.Add(child);
  54.                 }
  55.             }
  56.         }
  57.         return newEntity;
  58.     }
  59.  
  60.     /// <summary>
  61.     /// Recursively detaches entities from DomainContext, this
  62.     /// method detaches every navigation properties
  63.     /// of current Entity as well.
  64.     /// </summary>
  65.     /// <param name="context"></param>
  66.     /// <param name="entity"></param>
  67.     public static void Detach(this DomainContext context, Entity entity)
  68.     {
  69.         if (entity == null || entity.EntityState == EntityState.Detached)
  70.             return;
  71.         EntitySet nes = context.EntityContainer.GetEntitySet(entity.GetType());
  72.         nes.Detach(entity);
  73.  
  74.         Type entityType = typeof(Entity);
  75.  
  76.         // get all navigation properties…
  77.         Type type = entity.GetType();
  78.         foreach (var item in type.GetProperties())
  79.         {
  80.             if (entityType.IsAssignableFrom(item.PropertyType))
  81.             {
  82.                 Detach(context,item.GetValue(entity, null) as Entity);
  83.                 continue;
  84.             }
  85.             if (item.PropertyType.Name.StartsWith("EntityCollection"))
  86.             {
  87.                 IEnumerable coll = item.GetValue(entity, null) as IEnumerable;
  88.                 foreach (Entity child in coll)
  89.                 {
  90.                     Detach(context,child);
  91.                 }
  92.             }
  93.         }
  94.     }
  95.  
  96. }

Share
Tagged with: