Similar talk to last week - just thinned down a bit (not everyone in the room was a mobile dev) and also I had slightly longer to talk and managed to pace it better.
Friday, March 30, 2012
Monday, March 26, 2012
Some HTML, Javascript, Jquery, D3.js and CoffeeScript magic - a bit like an html pivotviewer
I put this demo together last week for a school project - http://slodge.com/teach/
It uses all sorts of html and js goodness inside and it's definitely at prototype stage - but I'm thinking about ways it could grow and change....
Ideally I'd quite like to get access to raw data from school SIMS databases. I will investigate further - but I am not paying GBP5000 for an SDK
MvvmCross slides from my @wpug talk last week
Slides from my @wpug talk last week - will shorten them for this week's DevEvening talk - always learning :)
Saturday, March 24, 2012
Update on MvvmCross - SQLBits conference app
I've been working on a lot of Mvvm on MonoTouch, MonoDroid and WP7 recently - and I've added a bit of WinRT too.
I've built an Mvvm framework - mvvmcross for this - and it enables code sharing and databinding acoss all the platforms.
As an example app, I've just built and released the SQL Bits conference app. Source code is on https://github.com/slodge/MvvmCrossConference and screenshots are below:
On WP7:
On Android:
On iOS:
All of these apps are **Native apps** using MvvmCross on top of WP7 SDK, MonoTouch and MonoDroid
Monday, February 20, 2012
MvvmCross - Mvvm Across WP7, MonoDroid and MonoTouch
This is just a quick intro post for now... a more full story will follow when I get a bit more of that "spare time" thing, including time to write a few more samples.
I've recently been working on a big cross-platform mobile project targeting Wp7, Android and iPhone. As an inspiration for this we started using the MonoCross platform (http://code.google.com/p/monocross/) although we quickly discovered that MVVM rather than MVC was the way we wanted to go, especially as we were working WP7-first.
As a detailed example, consider the details view for a Customer.
I've recently been working on a big cross-platform mobile project targeting Wp7, Android and iPhone. As an inspiration for this we started using the MonoCross platform (http://code.google.com/p/monocross/) although we quickly discovered that MVVM rather than MVC was the way we wanted to go, especially as we were working WP7-first.
To enable this project, we've built our own MVVM framework - MvvmCross - available under a MS-PL license on GitHub at https://github.com/slodge/MvvmCross
Explaining the framework is going to take a little time... and so will have to wait for a longer series of posts. However, as a quick introduction, the Customer Management sample currently builds and runs across the three major platforms - https://github.com/slodge/MvvmCross/tree/master/Sample%20-%20CustomerManagement
This sample has:
- a shared ViewModel and Model project - https://github.com/slodge/MvvmCross/tree/master/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement - this allows us to use the exact same C# logic across all 3 platforms, with our Dependency Injection framework providing platform specific implementations and optimisations where absolutely necessary.
- separate UI projects for each of the WP7, Touch and Droid projects - so that each UI can take advantage of platform-specific UI look and feel, user controls, etc.
As a detailed example, consider the details view for a Customer.
- In the shared project, this ViewModel is just a set of INotifyPropertyChanged properties and some IMvxCommand properties - see: https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement/ViewModels/DetailsCustomerViewModel.cs
- In the WP7 UI, the ViewModel is represented purely in XAML - e.g. in DataBinding statements like:
[TextBlock Text="{Binding Customer.Name}"/]
https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.WindowsPhone/Views/CustomerView.xaml
- In the Android UI, the ViewModel is represented purely in Android XML - e.g. in Mvx DataBinding attributes like
[TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:textAppearance="?android:attr/textAppearanceLarge" customermanagement:mvxbind="{'Text':{'Path':'Customer.Name'}}"/]
https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.Droid/Resources/Layout/Page_DetailsCustomerView.axml
- And in the Touch UI, the ViewModel is represented using a slightly modified version of the MonoTouch.Dialog UI
new StringElement("Name").Bind(this, "{'Value':{'Path':'Customer.Name'}}"),
https://github.com/slodge/MvvmCross/blob/master/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.Touch/Views/CustomerView.cs
- If that's not enough for you.... there is also a (not yet fully formed) port of MvvmCross to the full .Net framework - so you can run your viewmodels through a Console UI... with MonoMac, WPF, Silverlight and WinRT/Metro UIs also possible.
Interested? Confused? Want to know more?
Well the source code is there to play with... and I will post some more samples and some more info soon... possibly on a blog with better code formatting!
One warning though... some of the code still needs a little finishing... especially the Touch/Dialog integration - only a few Elements are currently bound. If anyone wants to help... please let me know!
Friday, January 27, 2012
DropShadow and "glow" on WP7
Doing background glow on WP7...
Proper blog post to follow
But in the meantime, the app is: http://www.windowsphone.com/en-US/apps/9ea0ba3d-7d73-4325-9d5c-a9aca3802ad2
And the source is... to follow... soon....
Saturday, November 19, 2011
MonoCross - a different kind of WP7 project approach
Just thought I'd drop a note about MonoCross. The first Wp7 code was only made available this week and so I've only had a few days to play with it. So far I'm finding it fascinating as an alternative way of thinking about how to construct an app.
I know not everyone is doing multiplatform... and I'm already finding that MonoCross gets in the way of some MVVM and data binding stuff, but I'm also finding that there are some very interesting parts to the way MX approaches development - in particular:
- MX splits the Model and Controller out into one class library, then puts the Views into the app project
- MX Views are ultimately PhoneApplicationPage's but you inherit via an MXView<TModel> class - it's quite nice that this means you always get a Model to use
- The navigation framework intercepts the calls to "routes" like "{Controller}/{Action}/{Id}" - so you no longer have to navigate to urls like "Views/EditThing.xaml?ThingId=12" and the navigation framework also takes care of the Model creation/selection for you.
There's plenty of "rough parts" in there - plenty that will get done differently in the future (e.g. there are static class and static member variables everywhere - Mx desparately needs an injection of IoC) and I'm not sure how blendable this approach is - but overall it's very interesting to see an application structured differently - something other than yet another Mvvm platform.
If you're interested, check it out on http://bit.ly/smT0Di
Stuart
P.S. Just in case you were wondering - I've nothing to do with the MX project - it's got some sort of book publisher behind it. I'm just one of the first 1.0 users (I think!)
Wednesday, November 16, 2011
Tuesday, November 15, 2011
Using MXTabActivityView in MonoCross (MonoDroid flavour)
1. In your application project, add your model - this model will be *shared* by all views within the tabs, plus also shared by the parent tabview itself:
public class FirstModel
{
public List<string> Items1 { get; set; }
public List<string> Items2 { get; set; }
public FirstModel()
{
Items1 = new List<string>()
{
"one",
"two",
"three"
};
Items2 = new List<string>()
{
"hello",
"world",
"monocross"
};
}
}
2. Again in your application project, add your controller:
public class FirstController : MXController<FirstModel>
{
public override string Load(Dictionary<string, string> parameters)
{
Model = new FirstModel();
return ViewPerspective.Default;
}
}
3. Finally in the application project, make sure you have a route setup for the controller - e.g. a default route like:
NavigationMap.Add("", new Controllers.FirstController());
4. In your Android container, add the activity views which will sit inside the tabs - e.g.:
[Activity(Label = "First View!")]
public class FirstView : MXListActivityView<FirstModel>
{
public override void Render()
{
ListView.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, Model.Items1.OrderBy(x => x).ToList() );
}
}
and:
[Activity(Label = "Second View!")]
public class SecondView : MXListActivityView<FirstModel>
{
public override void Render()
{
ListView.Adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, Model.Items2 );
}
}
5. In your Android container project, set up your tab activity view - this is a bit like http://docs.xamarin.com/android/tutorials/User_Interface/tab_layout
Set up the xml resource - e.g.:
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
</FrameLayout>
</LinearLayout>
</TabHost>
Also, add the tab icons if you want them (see notes in http://docs.xamarin.com/android/tutorials/User_Interface/tab_layout)
Then for the MXTabActivityView:
[Activity(Label = "A TabView!")]
public class TabView : MXTabActivityView<FirstModel>
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.TabHost);
TabHost.TabSpec spec; // Resusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent(this, typeof(FirstView));
intent.AddFlags(ActivityFlags.NewTask);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = TabHost.NewTabSpec("first");
spec.SetIndicator("First", Resources.GetDrawable(Resource.Drawable.ic_tab_artists));
spec.SetContent(intent);
TabHost.AddTab(spec);
intent = new Intent(this, typeof(SecondView));
intent.AddFlags(ActivityFlags.NewTask);
spec = TabHost.NewTabSpec("second");
spec.SetIndicator("Second", Resources.GetDrawable(Resource.Drawable.ic_tab_artists));
spec.SetContent(intent);
TabHost.AddTab(spec);
}
public override void Render()
{
// nothing to do here currently!
}
}
}
6. That's it! run and enjoy :)
Wednesday, November 09, 2011
Storage scopes cannot be created when _AppStart is executing.
If you see this error when running ASP.Net MVC apps:
Storage scopes cannot be created when _AppStart is executing.
Then don't panic - it seems this is just a Cassini problem - if you switch across to IIS express or to a real IIS server then the problem doesn't exist
(phew)
Friday, November 04, 2011
A honey trap - if anyone's running PHPMyAdmin then people will come looking!
I left a website running for a month on Azure... this is what came attacking:
| 404 | /phpmyadmin/scripts/setup.php | 23 |
| 404 | /pma/scripts/setup.php | 14 |
| 404 | /myadmin/scripts/setup.php | 11 |
| 404 | /content/images/skins/simple/awesome-overlay-sprite.png | 8 |
| 404 | /mysql/scripts/setup.php | 6 |
| 404 | /scripts/setup.php | 6 |
| 404 | /robots.txt | 5 |
| 400 | /w00tw00t.at.blackhats.romanian.anti-sec:) | 5 |
| 404 | /pma2005/scripts/setup.php | 4 |
| 404 | /phpmyadmin2/scripts/setup.php | 4 |
| 404 | /web/phpmyadmin/scripts/setup.php | 4 |
| 404 | /user/soapcaller.bs | 3 |
| 404 | /cube/readme | 3 |
| 404 | /round/readme | 3 |
| 404 | /roundcube-0.2/readme | 3 |
| 404 | /roundcube-0.1/readme | 3 |
| 404 | /roundcubemail-0.1/readme | 3 |
| 404 | /roundcubemail-0.2/readme | 3 |
| 404 | /wm/readme | 3 |
| 404 | /webmail2/readme | 3 |
| 404 | /rms/readme | 3 |
| 404 | /mail2/readme | 3 |
| 404 | /mss2/readme | 3 |
| 404 | /mss/readme | 3 |
| 404 | /roundcubemail/readme | 3 |
| 404 | /rc/readme | 3 |
| 404 | /webmail/readme | 3 |
| 404 | /roundcube/readme | 3 |
| 404 | /mail/readme | 3 |
| 404 | /readme | 3 |
| 404 | /manager/html | 3 |
| 404 | /sql/scripts/setup.php | 3 |
| 404 | /mysqladmin/scripts/setup.php | 3 |
| 404 | /phpmya/scripts/setup.php | 3 |
| 404 | /phpmyadmin1/scripts/setup.php | 3 |
| 404 | /phpmyadmin/config/config.inc.php | 3 |
| 404 | /mini-profiler-results | 2 |
| 404 | /sslmysqladmin/scripts/setup.php | 2 |
| 404 | /admin/phpmyadmin/scripts/setup.php | 2 |
| 404 | /admin/scripts/setup.php | 2 |
| 404 | /bbs/data/scripts/setup.php | 2 |
| 404 | /cpadmin/scripts/setup.php | 2 |
| 404 | /cpadmindb/scripts/setup.php | 2 |
| 404 | /cpanelmysql/scripts/setup.php | 2 |
| 404 | /cpanelphpmyadmin/scripts/setup.php | 2 |
| 404 | /cpanelsql/scripts/setup.php | 2 |
| 404 | /cpdbadmin/scripts/setup.php | 2 |
| 404 | /cpphpmyadmin/scripts/setup.php | 2 |
| 404 | /db/scripts/setup.php | 2 |
| 404 | /dbadmin/scripts/setup.php | 2 |
| 404 | /mysql-admin/scripts/setup.php | 2 |
| 404 | /mysqladminconfig/scripts/setup.php | 2 |
| 404 | /p/m/a/scripts/setup.php | 2 |
| 404 | /mysqlmanager/scripts/setup.php | 2 |
| 404 | /php-my-admin/scripts/setup.php | 2 |
| 404 | /php-myadmin/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.2.3/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.2.6/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.4/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.5-pl1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.5-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.5-rc1config/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.5/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.6-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.6-rc2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.6/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.7-pl1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.5.7/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-alpha2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-beta1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-beta2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-pl1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-pl2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-pl3/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-rc2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0-rc3/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.0/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.1-pl1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.1-pl2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.1-pl3/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.1-rc2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.2-beta1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.2-pl1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.2-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.3-pl1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.3-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.3/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.4-pl2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.4-pl3/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.4-pl4/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.4-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.6.4/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.7.0-beta1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.7.0-pl2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.7.0-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.7.0-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.7.0/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.0-beta1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.0-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.0-rc2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.0.1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.0.2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.0.4/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.1-rc1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.1/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2.8.2/scripts/setup.php | 2 |
| 404 | /phpmyadmin-2/scripts/setup.php | 2 |
| 404 | /phpadmin/scripts/setup.php | 2 |
| 404 | /phpmanager/scripts/setup.php | 2 |
| 404 | /phpmy-admin/scripts/setup.php | 2 |
| 404 | /roundcube/scripts/setup.php | 2 |
| 404 | /sl2/data/scripts/setup.php | 2 |
| 404 | /sqladmin/scripts/setup.php | 2 |
| 404 | /sqlmanager/scripts/setup.php | 2 |
| 404 | /sqlweb/scripts/setup.php | 2 |
| 404 | /typo3/phpmyadmin/scripts/setup.php | 2 |
| 404 | /web/scripts/setup.php | 2 |
| 404 | /webadmin/scripts/setup.php | 2 |
| 404 | /webdb/scripts/setup.php | 2 |
| 404 | /websql/scripts/setup.php | 2 |
| 404 | /xampp/phpmyadmin/scripts/setup.php | 2 |
| 404 | /~/pma/scripts/setup.php | 2 |
| 404 | /phpmyadmin2/config.inc.php | 2 |
| 404 | /backup/phpmyadmin/scripts/setup.php | 2 |
| 404 | /bkup/phpmyadmin/scripts/setup.php | 2 |
| 404 | /_phpmyadmin/scripts/setup.php | 2 |
| 404 | /phpmy/scripts/setup.php | 2 |
| 404 | /phpmyadmin/index.php | 2 |
| 404 | /phpmyadmin2/index.php | 2 |
| 404 | /phpmyadmin3/index.php | 2 |
| 404 | /cgi-bin/if.cgi | 2 |
| 404 | /admin/pma/scripts/setup.php | 1 |
| 404 | /mail/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.5.5-rc2/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.7.0-pl1/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.8.0.3/scripts/setup.php | 1 |
| 404 | /phppgadmin/scripts/setup.php | 1 |
| 404 | /webmail/scripts/setup.php | 1 |
| 404 | /~/admin/scripts/setup.php | 1 |
| 404 | /~/myadmin/scripts/setup.php | 1 |
| 404 | /~/phpadmin/scripts/setup.php | 1 |
| 404 | /~/phpmyadmin/scripts/setup.php | 1 |
| 404 | /pma/config/config.inc.php | 1 |
| 404 | /admin/config/config.inc.php | 1 |
| 404 | /dbadmin/config/config.inc.php | 1 |
| 404 | /mysql/config/config.inc.php | 1 |
| 404 | /php-my-admin/config/config.inc.php | 1 |
| 404 | /myadmin/config/config.inc.php | 1 |
| 404 | /config/config.inc.php | 1 |
| 404 | /phppgadmin/config.inc.php | 1 |
| 404 | /mail/config.inc.php | 1 |
| 404 | /webmail/config.inc.php | 1 |
| 404 | /wall/data/carbonapple_mono1024.jpg | 1 |
| 404 | /3rdparty/phpmyadmin/scripts/setup.php | 1 |
| 404 | /_admin/scripts/setup.php | 1 |
| 404 | /admm/scripts/setup.php | 1 |
| 404 | /admn/scripts/setup.php | 1 |
| 404 | /databaseadmin/scripts/setup.php | 1 |
| 404 | /phpm/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.11.10/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.11.1-all-languages/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.11.8.1-all-languages-utf-8-only/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.6.0-alpha/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.6.1-rc1/scripts/setup.php | 1 |
| 404 | /phpmyadmin-2.8.0/scripts/setup.php | 1 |
| 404 | /phpmyadmin-3.0.0-rc1-english/scripts/setup.php | 1 |
| 404 | /phpmyadmi/scripts/setup.php | 1 |
| 404 | /phpmyad/scripts/setup.php | 1 |
| 404 | /phpmyad-sys/scripts/setup.php | 1 |
| 404 | /php/scripts/setup.php | 1 |
| 404 | /vhcs2/tools/pma/scripts/setup.php | 1 |
| 404 | /wp-content/plugins/wp-phpmyadmin/wp-phpmyadmin/phpmyadmin/scripts/setup.php | 1 |
| 404 | /wp-phpmyadmin/phpmyadmin/scripts/setup.php | 1 |
| 404 | /wp-phpmyadmin/scripts/setup.php | 1 |
| 404 | /nosuichfile.php | 1 |
| 404 | /noxdir/nosuichfile.php | 1 |
| 404 | /pma/index.php | 1 |
| 404 | /mysql/index.php | 1 |
| 404 | /myadmin/index.php | 1 |
Subscribe to:
Posts (Atom)