Styling slider control

Here is sample on styling slider control to display the value of the slider in the Thumb

slider1

All the changes are in the Style of the slider. I added a converter to round the value as we dont want to see the value in decimals

you can download the code here

Using asp.net Membership and profile providers with RIA Services

After reading about RIA services. I wanted to write some sample code to hook into asp.net Membership and profile providers.

So I wrote couple of custom providers.

MembershipProvider

I had a simple table with UserID,UserName,Email and password columns
I did not bother with all the different overloads. I have just added code in few places like Initialize, GetUser, ValidateUser and CreateUser

ProfileProvider

I created a table which will store 3 values for each user, Theme, City and State

again I did not code for all the different overloads. I have added code for Initialize, SetPropertyValues, GetPropertyValues

once I had these providers in place

I added a Silverlight application with Webproject

and modified the Web.config file to add my providers

 <membership defaultProvider=”SampleMembershipProvider1″ >
      <providers>
        <clear/>
        <add name=”SampleMembershipProvider1″ type=”CustomProviders.SampleMembershipProvider” connectionStringName=”constring” enablePasswordRetrieval=”true” enablePasswordReset=”true” requiresQuestionAndAnswer=”true” writeExceptionsToEventLog=”false”/>
      </providers>
    </membership>

    <profile defaultProvider=”SampleProfileProvider1″>
      <providers>
        <add name=”SampleProfileProvider1″ type=”CustomProviders.SampleProfileProvider” connectionStringName=”constring” />
      </providers>
      <properties>
        <add name=”Theme” type=”System.Int32″ allowAnonymous=”true”/>
        <add name=”City” type=”System.String” allowAnonymous=”true”/>
        <add name=”State” type=”System.String” allowAnonymous=”true”/>
      </properties>
    </profile>

The next step is to add a new DomainService to the webproject
Adding the following code will get us started

[EnableClientAccess]
    public class Authentication : AuthenticationBase<UserBase> { }

as we have a profile also,created another class User inheriting from UserBase

 [EnableClientAccess]
    public class Authentication : AuthenticationBase<User> { }
    public class User : UserBase
    {
        public int Theme { get; set; }
        public string City { get; set; }
        public string State { get; set; }
    }

I added the following class so that we can have a Page(UI) in Silverlight which allows for user Registration

    [EnableClientAccess]
    public class MembershipService : DomainService
    {
        [ServiceOperation]
        public void AddUser(string userName, string password, string email)
        {
            MembershipCreateStatus createStatus;

            Membership.CreateUser(userName, password, email, null, null, true, out createStatus);
            if (createStatus != MembershipCreateStatus.Success)
            {
                throw new DomainServiceException(createStatus.ToString());
            }
        }
    }

We also need to add a Service to App.XAML
 <Application.Services>
        <appsvc:WebUserService x:Name=”UserService” />
    </Application.Services>
The sample does not have any UI, but when the page is loaded it will create a user and login the user as you can see from the code below

 public partial class MainPage : UserControl
    {
        UserService service;
        public MainPage()
        {
            InitializeComponent();
            CreateUser();                             
        }

        void CreateUser()
        {
            MembershipContext ctx = new MembershipContext();
            ctx.AddUserCompleted += new EventHandler<System.Windows.Ria.Data.InvokeEventArgs>(ctx_AddUserCompleted);
            ctx.AddUser(“user1”, “test”, “user@test.com“);
        }
        void ctx_AddUserCompleted(object sender, System.Windows.Ria.Data.InvokeEventArgs e)
        {
            MessageBox.Show(“User added”);
            Login();
        }

        void Login()
        {
            service = App.Current.Services[“UserService”] as UserService;
            service.LoginCompleted += new EventHandler<LoginCompletedEventArgs>(service_LoginCompleted);
            service.Login(“user1”, “test”);
        }
        void service_LoginCompleted(object sender, LoginCompletedEventArgs e)
        {
            User user = (service.User as User);
            if (string.IsNullOrEmpty(user.City))
            {
                user.City = “dallas”;
                user.State = “TX”;
                user.Theme = 100;
                service.SaveUserCompleted += new EventHandler<SaveUserCompletedEventArgs>(service_SaveUserCompleted);
                service.SaveUser();

            }           
        }

        void service_SaveUserCompleted(object sender, SaveUserCompletedEventArgs e)
        {
            MessageBox.Show(“login success and profile properies set”);
        }
    }

you can download the code here

RIA Services – sample

This sample doesnt do a whole lot but, I had to post in the forums twice to even get this working. so I thought it might be helpful to point out some of the issues I faced and how to solve similar problems. All it does is display list of customers and when you click on details, it shows details of the customer and his orders in a childwindow

The following is the reply clarfying the scenario from David
To be clear regarding EF and DomainDataSource, this is not a general issue — it should only present itself when a LoadSize is set because EF doesn’t support Skip() and Take() on unordered data. This would be the case even if you were using the underlying DomainContext to perform the same operations.

Ultimately, it’s an EF limitation. As long as the queries on your DomainService support Skip and Take, you can expect the DomainDataSource to work just fine (with LoadSize and PageSize) with them. Similarly, if your DomainService queries don’t support OrderBy(), ThenBy() or Where(), you shouldn’t expect sorting, grouping, or filtering to work using the DomainDataSource. Nonetheless, we’re looking at some ways to make it less likely that people will encounter this issue.In regards to your other issue with the DataPager, there may be a bug here that we will look into. My hunch is that it’s a timing issue, which is why setting the PageSize on the DDS fixes the problem.”

ria41
ria42
1. if we are using EntityFramework then the DomainDataSource  might not work correctly. you have to specify SortDescriptors(in bold)

  <riaControls:DomainDataSource x:Name=”source” LoadSize=”30″   LoadMethodName=”LoadCustomers” >
            <riaControls:DomainDataSource.DomainContext>
                <ds:NorthwindContext/>
            </riaControls:DomainDataSource.DomainContext>
            <riaControls:DomainDataSource.SortDescriptors>
                <riaData:SortDescriptor PropertyPath=”CustomerID” Direction=”Ascending” />
            </riaControls:DomainDataSource.SortDescriptors>
        </riaControls:DomainDataSource>

2. I Had a situation where I am calling a parameterized constructor

Details details = new Details((sender as Button).DataContext as Customers);
            details.Show();

and in the details page

public Details(Customers c)
        {
            InitializeComponent();          
            dataForm1.CurrentItem = c;
Parameter p = new Parameter();
            p.ParameterName = “customerId”;
            p.Value = c.CustomerID;
            source.LoadParameters.Add(p);
            source.Load();
        }

The above code is throwing exceptions when PageSize is specified on the DataPager, to get around that we need to specify on the DomainDataSource

you can download the code here (it is a bit big as database is also included in it)

Silverlight 3 – RIA Services

I started playing with the beta bits of the RIA Services and started to create a simple app, where list of customers will be displayed in a DataGrid  and a page size of 10 and will be edited using DataForm.

This is the XAML I had

<UserControl xmlns:dataControls=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm”  xmlns:data=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”  x:Class=”SilverlightApplication10.MainPage”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
             xmlns:riaControls=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls”
             xmlns:riaData=”clr-namespace:System.Windows.Data;assembly=System.Windows.Ria.Controls”
             xmlns:domain=”clr-namespace:SilverlightApplication10.Web”
    Width=”800″ Height=”600″>
    <Grid Margin=”10″ x:Name=”LayoutRoot” Background=”White”>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <riaControls:DomainDataSource x:Name=”source” LoadSize=”100″   LoadMethodName=”LoadCustomers” AutoLoad=”True”>
            <riaControls:DomainDataSource.DomainContext>
                <domain:NorthwindContext />
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
        <StackPanel>
             <dataControls:DataPager PageSize=”10″   Source=”{Binding Data, ElementName=source}” />
        <data:DataGrid x:Name=”datagrid1″ ItemsSource=”{Binding Data, ElementName=source}” IsReadOnly=”True” AutoGenerateColumns=”False” >
            <data:DataGrid.Columns>
                <data:DataGridTextColumn Header=”Customer ID” Binding=”{Binding CustomerID}”/>
                <data:DataGridTextColumn  Header=”Contact Name” Binding=”{Binding ContactName}”/>
                <data:DataGridTextColumn  Header=”Contact Title” Binding=”{Binding ContactTitle}”/>
            </data:DataGrid.Columns>
        </data:DataGrid>
        </StackPanel>       
            <!–<dataControls:DataForm WrapAfter=”4″ AutoEdit=”True”     Header=”Customer Details”  CurrentItem=”{Binding ElementName=datagrid1, Path=SelectedItem}” Grid.Row=”1″></dataControls:DataForm>–>
      
    </Grid>
</UserControl>

ria1

everything  looks good,  clicked the button in the pager to go to the lastpage, there are only 91 records, so not sure if the pager is displaying loadsize/pagesize as number of pages, but I get this. cannot go to the first page. looks like it knows there are is no data in Page 10, and but the UI is not reflecting that.  if we click the next button in the pager we go to 2nd page

ria2

When the loadsize is specified to something less than 91 (say 30), I can see data for 3 pages but when I navigate to 4th page, I dont  get data

I uncommented the DataForm and ran the sample

ria3

I noticed the following

1. Pager functionality not there

2. AutoEdit  on the DataForm is set to true, so it goes into edit mode and displays Save and Cancel buttons. Cancel is grayed out and it shows there are some pending changes. if we select another Item in the datagrid everything is good.

3. If I remove the AutoEdit  on DataForm  pager seems to work, but when I go to next page, Datagrid doesnt select the first item by default so the DataForm is empty

Getting started with DataForm

you can find an updated sample here https://leeontech.wordpress.com/2009/07/27/working-with-dataform/

DataForm is one of the new controls in Silverlight 3.  

I started with some xml data,  got customer information and bunch of orders

<data>
<Customers CustomerID=”ALFKI” CompanyName=”Alfreds Futterkiste” ContactName=”Maria Anders” ContactTitle=”Sales Representative” Address=”Obere Str. 57″ City=”Berlin” PostalCode=”12209″ Country=”Germany” Phone=”030-0074321″ Fax=”030-0076545″>
  <Orders OrderID=”10643″ CustomerID=”ALFKI” EmployeeID=”6″ OrderDate=”1997-08-25″ RequiredDate=”1997-09-22″ ShippedDate=”1997-09-02″ ShipVia=”1″ Freight=”29.4600″ ShipName=”Alfreds Futterkiste” ShipAddress=”Obere Str. 57″ ShipCity=”Berlin” ShipPostalCode=”12209″ ShipCountry=”Germany” />
  <Orders OrderID=”10692″ CustomerID=”ALFKI” EmployeeID=”4″ OrderDate=”1997-10-03″ RequiredDate=”1997-10-31″ ShippedDate=”1997-10-13″ ShipVia=”2″ Freight=”61.0200″ ShipName=”Alfred’s Futterkiste” ShipAddress=”Obere Str. 57″ ShipCity=”Berlin” ShipPostalCode=”12209″ ShipCountry=”Germany” />
  <Orders OrderID=”10702″ CustomerID=”ALFKI” EmployeeID=”4″ OrderDate=”1997-10-13″ RequiredDate=”1997-11-24″ ShippedDate=”1997-10-21″ ShipVia=”1″ Freight=”23.9400″ ShipName=”Alfred’s Futterkiste” ShipAddress=”Obere Str. 57″ ShipCity=”Berlin” ShipPostalCode=”12209″ ShipCountry=”Germany” />
  <Orders OrderID=”10835″ CustomerID=”ALFKI” EmployeeID=”1″ OrderDate=”1998-01-15″ RequiredDate=”1998-02-12″ ShippedDate=”1998-01-21″ ShipVia=”3″ Freight=”69.5300″ ShipName=”Alfred’s Futterkiste” ShipAddress=”Obere Str. 57″ ShipCity=”Berlin” ShipPostalCode=”12209″ ShipCountry=”Germany” />
  <Orders OrderID=”10952″ CustomerID=”ALFKI” EmployeeID=”1″ OrderDate=”1998-03-16″ RequiredDate=”1998-04-27″ ShippedDate=”1998-03-24″ ShipVia=”1″ Freight=”40.4200″ ShipName=”Alfred’s Futterkiste” ShipAddress=”Obere Str. 57″ ShipCity=”Berlin” ShipPostalCode=”12209″ ShipCountry=”Germany” />
  <Orders OrderID=”11011″ CustomerID=”ALFKI” EmployeeID=”3″ OrderDate=”1998-04-09″ RequiredDate=”1998-05-07″ ShippedDate=”1998-04-13″ ShipVia=”1″ Freight=”1.2100″ ShipName=”Alfred’s Futterkiste” ShipAddress=”Obere Str. 57″ ShipCity=”Berlin” ShipPostalCode=”12209″ ShipCountry=”Germany” />
  <Orders OrderID=”11078″ CustomerID=”ALFKI” OrderDate=”2008-12-31T02:06:47.913″ RequiredDate=”1998-05-07″  ShipName=”Name” ShipAddress=”Address” ShipCity=”City” ShipRegion=”Region” ShipPostalCode=”ZipCode” ShipCountry=”Country” />
</Customers>

</data>

Drag and drop a DataForm from the toolbox will give us  the following after giving a name

 <dataControls:DataForm Header=”Customer Details”  Width=”500″ Height=”350″ x:Name=”form1″  />

once I set the ItemsSource  to a list of objects that are created from the above data, I got

dataform11

I dont want the Orders displayed like above so I changed the XAML to look like this

<StackPanel>
     <dataControls:DataForm Header=”Customer Details”  Width=”500″ Height=”350″ x:Name=”form1″  >
     </dataControls:DataForm>
     <TextBlock Text=”List of Orders” Width=”500″></TextBlock>
     <data:DataGrid Width=”500″ ItemsSource=”{Binding ElementName=form1, Path=CurrentItem.Orders}”></data:DataGrid>
</StackPanel>

Here is what I got

dataform2

I dont want to have the Orders property show up in the DataForm as are displaying in a  list in a DataGrid.  so changed the XAML to add fields to be displayed

<StackPanel>
            <dataControls:DataForm WrapAfter=”4″ Header=”Customer Details” AutoGenerateFields=”False”  Width=”500″ Height=”200″ x:Name=”form1″  >
                <dataControls:DataForm.Fields>
                    <dataControls:DataFormTextField  FieldLabelContent=”Customer ID” Binding=”{Binding CustomerID}”></dataControls:DataFormTextField>
                    <dataControls:DataFormTextField  FieldLabelContent=”Contact Title” Binding=”{Binding ContactTitle}”></dataControls:DataFormTextField>
                    <dataControls:DataFormTextField  FieldLabelContent=”Contact Name” Binding=”{Binding ContactName}”></dataControls:DataFormTextField>                   
                    <dataControls:DataFormTextField  FieldLabelContent=”City” Binding=”{Binding City}”></dataControls:DataFormTextField>
                    <dataControls:DataFormTextField  FieldLabelContent=”Country” Binding=”{Binding Country}”></dataControls:DataFormTextField>
                    <dataControls:DataFormTextField  FieldLabelContent=”Phone” Binding=”{Binding Phone}”></dataControls:DataFormTextField>
                </dataControls:DataForm.Fields>
            </dataControls:DataForm>
            <TextBlock Text=”List of Orders” Width=”500″></TextBlock>
            <data:DataGrid Width=”500″ ItemsSource=”{Binding ElementName=form1, Path=CurrentItem.Orders}”></data:DataGrid>
        </StackPanel>

got something more professional

dataform4

we can add some effects by adding this to the above XAML

 <StackPanel.Projection>
                <PlaneProjection RotationX=”-25″ RotationY=”-15″ RotationZ=”15″  />
            </StackPanel.Projection>

 

datdaform5

That is as far as I got with the little time I spent.

Creating RadiobuttonList

In Silverlight 3 beta1, RelativeSource and ElementName can be specified on the binding which will enable us to get rid of code. Here is a XAML for the RadiobuttonList using ListBox

 <ListBox ItemContainerStyle=”{StaticResource ListBoxItemStyle}” x:Name=”List1″>

we declare the style like this, style taken from the SDK

changes made – Added the xaml in bold and the original xaml commented in italics

<UserControl.Resources>
        <Style x:Key=”ListBoxItemStyle” TargetType=”ListBoxItem”>
            <Setter Property=”Padding” Value=”3″ />
            <Setter Property=”HorizontalContentAlignment” Value=”Left” />
            <Setter Property=”VerticalContentAlignment” Value=”Top” />
            <Setter Property=”Background” Value=”Transparent” />
            <Setter Property=”BorderThickness” Value=”1″/>
            <Setter Property=”TabNavigation” Value=”Local” />
            <Setter Property=”Template”>
                <Setter.Value>
                    <ControlTemplate TargetType=”ListBoxItem”>
                        <Grid Background=”{TemplateBinding Background}”>
                            <vsm:VisualStateManager.VisualStateGroups>
                                <vsm:VisualStateGroup x:Name=”CommonStates”>
                                    <vsm:VisualState x:Name=”Normal” />
                                    <vsm:VisualState x:Name=”MouseOver”>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName=”fillColor” Storyboard.TargetProperty=”Opacity” Duration=”0″ To=”.35″/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name=”SelectionStates”>
                                    <vsm:VisualState x:Name=”Unselected” />
                                    <vsm:VisualState x:Name=”Selected”>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName=”fillColor2″ Storyboard.TargetProperty=”Opacity” Duration=”0″ To=”.75″/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name=”FocusStates”>
                                    <vsm:VisualState x:Name=”Focused”>
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName=”FocusVisualElement” Storyboard.TargetProperty=”Visibility” Duration=”0″>
                                                <DiscreteObjectKeyFrame KeyTime=”0″>
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name=”Unfocused”/>
                                </vsm:VisualStateGroup>
                            </vsm:VisualStateManager.VisualStateGroups>
                            <Rectangle x:Name=”fillColor” Opacity=”0″ Fill=”#FFBADDE9″ IsHitTestVisible=”False” RadiusX=”1″ RadiusY=”1″/>
                            <Rectangle x:Name=”fillColor2″ Opacity=”0″ Fill=”#FFBADDE9″ IsHitTestVisible=”False” RadiusX=”1″ RadiusY=”1″/>
                            <RadioButton GroupName=”g1″ IsChecked=”{Binding Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}” Content=”{TemplateBinding Content}”/>
                            <!–<ContentPresenter
            x:Name=”contentPresenter”
            Content=”{TemplateBinding Content}”
            ContentTemplate=”{TemplateBinding ContentTemplate}”
            HorizontalAlignment=”Left”
            Margin=”{TemplateBinding Padding}”/>–>
                            <Rectangle x:Name=”FocusVisualElement” Stroke=”#FF45D6FA” StrokeThickness=”1″ Visibility=”Collapsed” RadiusX=”1″ RadiusY=”1″ />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </UserControl.Resources>

Showing and Hiding Series in chart

Lets say we have a chart like this

sh_series1

it kind of looks like too many lines and user doesnt have easy way to see the different trends or easily compare the different measures user wants.

Showing and hiding a particular series will be nice addition to charts to allow the user to pick and choose what to see.   we want the user to be able to click the legenditem to toggle the display of the series.

sh_series2

sh_series3

we will start adding a style for the LegendItem, the original style looks like this

 <Style TargetType=”charting:LegendItem”>
        <Setter Property=”IsTabStop” Value=”False” />
        <Setter Property=”Template”>
            <Setter.Value>
                <ControlTemplate TargetType=”charting:LegendItem”>
                    <StackPanel Orientation=”Horizontal”>
                        <Rectangle Width=”8″ Height=”8″ Fill=”{Binding Background}”
                                   Stroke=”{Binding BorderBrush}” StrokeThickness=”1″ Margin=”0,0,3,0″ />
                        <datavis:Title Content=”{TemplateBinding Content}” />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

and we specify the style on the LineSeries like this

<charting:LineSeries   LegendItemStyle=”{StaticResource LegendItemStyle}” Title=”Total Visits”
                                     IndependentValueBinding=”{Binding OrderDate}”
                                     DependentValueBinding=”{Binding Visits}” />            

As we want to provide a way for the user to toggle the visibility of the Series. we will re-style the LegendItem to use a CheckBox for this sample

 <Style x:Key=”LegendItemStyle” TargetType=”charting:LegendItem”>
            <Setter Property=”IsTabStop” Value=”False” />
            <Setter Property=”Template”>
                <Setter.Value>
                    <ControlTemplate TargetType=”charting:LegendItem”>
                        <CheckBox Click=”CheckBox_Click” Cursor=”Hand” IsChecked=”true”
                                  Content=”{TemplateBinding Content}” Tag=”{TemplateBinding Content}”>
                            <CheckBox.Template>
                                <ControlTemplate TargetType=”CheckBox”>
                                    <StackPanel Orientation=”Horizontal”>
                                        <Rectangle Width=”8″ Height=”8″ Fill=”{Binding Background}” Stroke=”{Binding BorderBrush}”
                                                   StrokeThickness=”1″ Margin=”0,0,3,0″ />
                                        <datavis:Title Content=”{TemplateBinding Content}” />
                                    </StackPanel>
                                </ControlTemplate>
                            </CheckBox.Template>
                        </CheckBox>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

(After posting I realized that instead of binding again to Tag we could base our condition on the content itself. Too lazy to change the code now)

To start with, we want all the series to be shown so we set the IsChecked property to “true”.

we added a click handler also to checkbox in which we are going to check the IsChecked property and decide if we want the series to be shown or hidden

private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox chk = (sender as CheckBox);
LineSeries ls = chart1.Series.Cast
().Where(s => s.Title.ToString() == chk.Tag.ToString()).ElementAtOrDefault(0);
if (chk.IsChecked.Value)
chk.Opacity = ls.Opacity = 1;
else
{
chk.Opacity = 0.5;
ls.Opacity = 0;
}
}

you can see a demo here and download the code here