I often forget about different conferences I would like to keep an eye on, so I decided to make a list of them on my blog.
Silverlight 4 + COM + SQL Server = Cool!
Today is the day to talk about COM possibilities in Silverlight 4. One would question the titles of my post. COM and Cool in the same sentence? Let me proof this title to you.
First, let me take a closer look at COM. In order to access COM, you must install Silverlight application on a local machine. The access to COM is not enabled when a Silverlight application is run in the browser. So, first of all you have to enable this by checking “Enable running application out of browser” checkbox in project properties. Second of all, you have to check “Require elevated trust…” checkbox in “Out-of-browser settings” area in project properties. Now, you are ready to install you application and test COM support. How about Word automation:
Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();var doc = word.Documents.Add();var paragraph = doc.Paragraphs.Add();paragraph.Range.Text = "Some text";
Now, let’s talk about database access. Parts of System.Data.SqlClient namespace are not exposed to COM by default. So, to enable database access we must write an assembly that is exposed to COM that wraps database access. To do so, check the property “Register for COM Interop” in project properties for the .NET (NOT Silverlight) based project that will fire off database queries for us. Once the assembly is built, I can just use RegAsm to register my DLL with COM on a machine. Of course, this would be a prerequisite to use Silverlight application for local data access. The other prerequisite is to have .NET Runtime installed on that machine as well. I could write an install project of course to make this process easier.
The next step is to write a Silverlight assembly that would use COM Interop similar to the one above for Word to talk to my database access .NET based assembly.
dynamic sqlDB = ComAutomationFactory.CreateObject("COMSQLClient.COMSqlDatabase");
Now the most exciting part. I created and published the project on CodePlex that does exactly what I just talked about. Check out the project and let me know what you think. You can download the source code and look into the implementation details. Here is the link to it:
http://silverlight4sqllib.codeplex.com/
Thanks.
The MSDN Southern Fried Roadshow
Glen Gordon, our local evangelist is doing another road show. Here are the event details.
Thursday, February 25, 2010 1:00 PM – Thursday, February 25, 2010 5:00 PM Eastern Time (US & Canada)
Welcome Time: 12:30 PM
Atlanta Marriot Alpharetta
5750 Windward Pkwy
Alpharetta Georgia 30005
United States
Language(s):
English.
Product(s):
Azure Services Platform, Microsoft technologies, Windows and Windows 7.
Audience(s):
Pro Dev/Programmer.
Presenter(s):
Glen Gordon, Joe Healy
Event Overview
MSDN Events presents: Take Your Applications Sky High with Cloud Computing and the Windows Azure Platform
Join your local MSDN Events team as we take a deep dive into cloud computing and the Windows Azure Platform. We’ll start with a developer-focused overview of this new platform and the cloud computing services that can be used either together or independently to build highly scalable applications. As the day unfolds, we’ll explore data storage, SQL Azure, and the basics of deployment with Windows Azure. Register today for these free, live sessions in your local area.
If you register and attend this event, you will be placed in a raffle to win a chance to bring home one (1) free copy of Windows 7 – you could be the lucky winner! Register today!
SESSION 1: Overview of Cloud Computing and Windows Azure
The Windows Azure platform is a set of high-performance cloud computing services that can be used together or independently and enable developers to leverage existing skills and familiar tools to develop cloud applications. In this session, we’ll provide a developer-focused overview of this new online service computing platform. We’ll explore the components, key features and real day-to-day benefits of Windows Azure.
Highlights include:
· What is cloud computing?
· Running web and web service applications in the cloud
· Using the Windows Azure and local developer cloud fabric
· Getting started – tools, SDKs and accounts
· Writing applications for Windows Azure
SESSION 2: Survey of Windows Azure Platform Storage Options
Durable data storage is a key component of any cloud computing offering. The Windows Azure Platform offers many options, which can be used alone or in combination. Windows Azure itself offers ready-to-use and lightweight storage in the form of tables, blobs, and queues. Another choice for storage is SQL Azure, a true relational database in the cloud. In this session, we’ll explore the highlights of these implementations and how to both create and use storage in each form. We’ll give you guidance on choosing the right forms of storage for your application scenarios.
Highlights include:
· Understanding table & blob storage
· Programming against table & blob storage
· Working with queue storage
· Managing credentials and connection strings
· Scaling and configuration
· Understanding SQL Azure databases versus local SQL Server databases
· SQL Azure firewall, logins and passwords
· Database creation, deployments and migrations
· Database management using SQL Management Studio
· Programming against SQL Azure databases
SESSION 3: Going Live with your Azure Solution
Windows Azure features a powerful, yet simple deployment model. By focusing on your application and abstracting away the infrastructure details, you can deploy almost any app with minimal fuss. In this session, we’ll walk you through the basics of Windows Azure deployment, including site monitoring, diagnostics and performance issues.
Highlights include:
· Start-to-Finish Visual Studio demonstration of a realistic XML data driven business web site from the desktop to the cloud.
· Windows Azure Deployments
· Start-to-Finish Visual Studio demonstration of a realistic SQL Server data driven business web site from the desktop to the cloud.
· Configuration of your application in the cloud
· Guidance and Suggestions to ensure your success
*Be sure to learn more about the TechNet event happening on the same day at the same location from 8:30am–12:00pm. If you are interested in attending, please register separately for that event here: http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439495&Culture=en-US
Registration Options
Event ID:
1032439974
Here is the link to this event:
http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439974&Culture=en-US
Entity Framework 4.0 and Multiple Data Contexts
In the EF version 1.0, there was a problem when one would try to update multiple contexts as part of a single transaction. For example, I can use Transaction Scope, the update one context, then second context. Here is sample code to illustrate:
using (TransactionScope scope = new TransactionScope()) { try { using (RolodexEntities context = new RolodexEntities()) { context.Connection.Open(); Company company = new Company(); company.CompanyName = "Test 1"; company.DateAdded = DateTime.Today; context.AddToCompanies(company); context.SaveChanges(); using (RolodexEntities context2 = new RolodexEntities(context.Connection as EntityConnection)) { Company company2 = new Company(); company2.CompanyName = "Test 1"; company2.DateAdded = DateTime.Today; context2.AddToCompanies(company2); context2.SaveChanges(); } } scope.Complete(); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
This code in version 1.0 would throw an exception when second context’s constructor was called. The exception was quite obscure and was referring to the fact that the connection was already open. This was actually correct, but that was the whole reason I was passing in the connection. I was trying to make sure that my transaction would not get promoted to Distributed Transactions Coordinator. The transaction would always get promoted as soon as there are multiple SQL Server connections used within using scope/.end using scope code block. So, in version 1.0 MSDTC would be required in the code above.
This issue still exists in EF 4.0. You can vote to fix the issue here : https://connect.microsoft.com/data/feedback/details/533240/cannot-share-a-store-connection-between-multiple-contexts-in-order-to-avoid-dtc-promotion
Here is the code that confirms the problem:
using (TransactionScope scope = new TransactionScope()) { try { using (RolodexEntities context = new RolodexEntities()) { context.Connection.Open(); Company company = new Company(); company.CompanyName = "Test 11"; company.DateAdded = DateTime.Today; context.AddToCompanies(company); context.SaveChanges(); RolodexEntities1 contextTemp = new RolodexEntities1(); MetadataWorkspace space = (contextTemp.Connection as EntityConnection).GetMetadataWorkspace(); EntityConnection connection = new EntityConnection(space, (context.Connection as EntityConnection).StoreConnection); using (RolodexEntities1 context2 = new RolodexEntities1(connection)) { User user = new User(); user.UserName = "test"; user.Role = "User"; context2.AddToUsers(user); context2.SaveChanges(); } } scope.Complete(); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
Please feel free to ask any questions on this subject.
Silverlight, MVVM and Animations
Yesterday I was asked about a way to play animations in MVVM environment.
So, I gave this some thought today, and came up with a few ideas.
First, and the easiest way is to separate ViewModel from animation by attaching an animation to a behavior. Here is how we would write the behavior:
public class MVVMSimpleAnimationBehavior : TargetedTriggerAction<UIElement>
{
protected override void Invoke(object parameter)
{
RunAnimation();
}
public Storyboard AnimationStoryBoard
{
get { return (Storyboard)GetValue(AnimationStoryBoardProperty); }
set { SetValue(AnimationStoryBoardProperty, value); }
}
public static readonly DependencyProperty AnimationStoryBoardProperty =
DependencyProperty.Register("AnimationStoryBoard", typeof(Storyboard), typeof(MVVMSimpleAnimationBehavior), new PropertyMetadata(null));
private void RunAnimation()
{
if (AnimationStoryBoard != null)
{
AnimationStoryBoard.Begin();
}
}
}
Pretty simple approach. Here is how would use animation in the XAML:
<Button Content="Behavior Test" Grid.Column="1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Now, I want to complicate the story a little bit. I really want to trigger an animation in the UI via an event in my model. I am going to start with a sample ViewModel. I want to have an event there that I will later use as a trigger for my animation. Here is what my ViewModel would look like:
public class SampleModel: INotifyPropertyChanged
{
public event EventHandler StartAnimation;
protected virtual void OnStartAnimation()
{
if (StartAnimation != null)
{
StartAnimation(this, EventArgs.Empty);
}
}
public void RaiseEvent()
{
OnStartAnimation();
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
My event is called StartAnimation. Now it is time to develop a more complicate behavior to support my event driven animation from ViewModel. I am going to actually combine new functionality with the simple behavior about and have multi-functional useful object. Here is what the final product looks like:
using System;
using System.Windows.Interactivity;
using System.Windows;
using System.Windows.Media.Animation;
using System.ComponentModel;
using System.Reflection;
namespace SLMVVMAnimationBehavior
{
public class MVVMAnimationBehavior : TargetedTriggerAction<UIElement>
{
private EventInfo info;
protected override void Invoke(object parameter)
{
RunAnimation(this, EventArgs.Empty);
}
public Storyboard AnimationStoryBoard
{
get { return (Storyboard)GetValue(AnimationStoryBoardProperty); }
set { SetValue(AnimationStoryBoardProperty, value); }
}
public static readonly DependencyProperty AnimationStoryBoardProperty =
DependencyProperty.Register("AnimationStoryBoard", typeof(Storyboard), typeof(MVVMAnimationBehavior), new PropertyMetadata(null));
public string EventName
{
get { return (string)GetValue(EventNameProperty); }
set { SetValue(EventNameProperty, value); }
}
public static readonly DependencyProperty EventNameProperty =
DependencyProperty.Register("EventName", typeof(string), typeof(MVVMAnimationBehavior), new PropertyMetadata(HandlModelChanged));
public object Model
{
get { return GetValue(ModelProperty); }
set { SetValue(ModelProperty, value); }
}
public static readonly DependencyProperty ModelProperty =
DependencyProperty.Register("Model", typeof(object), typeof(MVVMAnimationBehavior), new PropertyMetadata(HandlModelChanged));
private static void HandlModelChanged(object sender, DependencyPropertyChangedEventArgs e)
{
MVVMAnimationBehavior behavior = sender as MVVMAnimationBehavior;
object model = behavior.Model;
if (behavior.info != null)
{
behavior.info.RemoveEventHandler(model, Delegate.CreateDelegate(typeof(EventHandler), behavior, "RunAnimation"));
}
if (model != null && !string.IsNullOrEmpty(behavior.EventName))
{
behavior.info = model.GetType().GetEvent(behavior.EventName);
behavior.info.AddEventHandler(model, Delegate.CreateDelegate(typeof(EventHandler), behavior, "RunAnimation"));
}
}
private void RunAnimation(object sender, EventArgs e)
{
if (AnimationStoryBoard != null)
{
AnimationStoryBoard.Begin();
}
}
}
}
As you can see, I added two mode dependency properties – one for event name that will trigger the animation, the other one for ViewModel ( I actually called it model). Now the tricky part is to use a bit of reflection to attach an event handler to the event on my model. This is done in HandlModelChanged routine that is called when Model or Event name is set. I am getting an event, and attaching a handler to it. The actual handler is located inside the behavior itself – RunAnimation method. Here is what my fianl XAML looks like that is testing both animation approaches:
<UserControl x:Class="SLMVVMAnimationBehavior.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SLMVVMAnimationBehavior"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
<UserControl.Resources>
<Storyboard x:Name="TestStoryboard">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="textBlock" Storyboard.TargetProperty="(TextBlock.FontSize)">
<EasingDoubleKeyFrame KeyTime="00:00:00.1000000" Value="24"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.2000000" Value="21.333"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.3000000" Value="18.667"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.4000000" Value="16"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="13.333"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.6000000" Value="16"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.7000000" Value="18.667"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.8000000" Value="21.333"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.9000000" Value="24"/>
<EasingDoubleKeyFrame KeyTime="00:00:01" Value="26.667"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<local:SampleModel x:Key="CurrentModel" />
<local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}" Model="{StaticResource CurrentModel}" x:Key="Animation" EventName="StartAnimation"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="#FFF3EEEE" DataContext="{Binding Source={StaticResource CurrentModel}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button x:Name="TestButton" Content="Click To Start Animation" d:LayoutOverrides="Height" HorizontalAlignment="Left" Click="TestButton_Click"/>
<Button Content="Behavior Test" Grid.Column="1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<TextBlock x:Name="textBlock" Margin="0,0,0,6" Text="Sample Text" TextWrapping="Wrap" d:LayoutOverrides="Width, Height" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26.667"/>
</Grid>
</Grid>
</UserControl>
To summarize, I illustrate a couple of approaches to trigger animations in MVVM environment. Of course, there is always code-behind, but many developers frown at this approach..
Please let me know if you have any questions.