ページ

Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Tuesday, April 10, 2012

Kinect for Windows Simulator

It's not so hard a thing to get tips on Kinect , but I'm sometimes confused about how I should set up the sensor and how I can locate the stand correctly at various places.
So I created the simulation app by Silverlight.

Kinect Simulator
http://kinectsimulator.appspot.com/
*This is based on Microsoft Kinect technical specification.

Kinect for Windows
http://www.kinectforwindows.com/

Saturday, August 20, 2011

facebook and twitter application implemented in silverlight.

It's easy to create facebook and twitter application implemented in silverlight, but as for twitter, it doesn't work because of Cross-Domain matter.
So as one of the solutions, It should be implemented with 'Out of browser' & 'Elevated Trusted mode'.
Then, it will be a kind of desktop application.( I actually left 'Callback URL' blank. )

However, there's an important reminder about it.

How we can implant 'consumer_secret' into the application.
or
How we can let the application get/download 'consumer_secret' from somewhere else.

Well, I don't know the best practice, but I did encrypt the key as a countermeasure.
* Maybe, It's better to use web pages like asp.net before getting oauth_token and oauth_token_secret.

Anyway, I tried to create the applications because I wanted to know how 'OAuth 1.0a' and 'OAuth 2.0' work.

Silverlight client for facebook.
https://social-media-applications.appspot.com/facebook/silverlight/index.html

Silverlight client for twitter ( Out Of Browser ).
https://social-media-applications.appspot.com/twitter/silverlight/index.html


Get uri, query and headers

private void OAuth(string url, string httpMethod, Dictionary<string, string> parameters, out Uri uri, out string query, out Dictionary<HttpRequestHeader, string> headers)
{
    query = string.Empty;
    uri = null;
    headers = new Dictionary<HttpRequestHeader, string>();
    parameters["oauth_signature"] = string.Empty;
    var param = parameters.OrderBy(x => x.Key);

    StringBuilder sb = new StringBuilder();
    foreach (var p in param)
    {
        if (!string.IsNullOrEmpty(p.Value))
            sb.Append(@"&" + p.Key + "=" + UrlEncode(p.Value));
    }
            sb.Remove(0, 1);
    string signatureBase = string.Format(@"{0}&{1}&{2}", httpMethod.ToUpper(), UrlEncode(url), UrlEncode(sb.ToString()));

    HMACSHA1 hmacsha1 = new HMACSHA1();
    hmacsha1.Key = Encoding.UTF8.GetBytes(string.Format("{0}&{1}", UrlEncode(parameters["consumer_secret"]), UrlEncode(parameters["oauth_token_secret"])));
    byte[] dataBuffer = Encoding.UTF8.GetBytes(signatureBase);
    byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);

    string sig = Convert.ToBase64String(hashBytes);
    sb.Append(@"&oauth_signature=" + UrlEncode(sig));
    parameters["oauth_signature"] = sig;

    query = sb.ToString();
    string getURL = url;
    if (httpMethod.ToUpper().Equals("GET"))
    {
        if (!string.IsNullOrEmpty(query))
            getURL += '?' + query;
    }
    uri = new Uri(getURL, UriKind.RelativeOrAbsolute);
    if (httpMethod.ToUpper().Equals("POST"))
    {
        headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
        headers[HttpRequestHeader.Authorization] = GetHeader(uri, parameters);
    }
}


URL Encode

public string UrlEncode(string value)
{
    string urlChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
    StringBuilder result = new StringBuilder();
    byte[] data = Encoding.UTF8.GetBytes(value);
    for (int i = 0; i < data.Length; i++)
    {
        int c = data[i];
        if (c < 0x80 && urlChars.Contains((char)c))
            result.Append((char)c);
        else
            result.Append('%' + String.Format("{0:X2}", (int)data[i]));
    }
    return result.ToString();
}

Nonce

private string GetNonce()
{
    string nonceChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    StringBuilder result = new StringBuilder(8);
    Random random = new Random();
    for (int i = 0; i < 8; ++i)
        result.Append(nonceChars[random.Next(nonceChars.Length)]);
    return result.ToString();
}

Timestamp

private string GetTimestamp()
{
    TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
    return Convert.ToInt64(ts.TotalSeconds).ToString();
}

Authorization Header

private string GetHeader(Uri uri, Dictionary<string, string> parameters)
{
    StringBuilder realm = new StringBuilder();
    realm.Append(uri.Scheme);
    realm.Append("://");
    realm.Append(uri.Host);
    if (uri.Port != 80 && uri.Port != 443)
        realm.Append(':' + uri.Port);

    StringBuilder header = new StringBuilder();
    header.Append("Authorization: ");
    header.Append("OAuth realm=\"" + realm.ToString() + "\"");
    foreach (var p in parameters)
    {
            header.Append(", " + p.Key + "=\"" + UrlEncode(p.Value) + "\"");
    }
    header.Append("\r\n");
    return header.ToString();
}


Usage : Post message on your twitter

public void Tweet(string message)
{
    Dictionary<string, string> param = new Dictionary<string, string>();
    param["oauth_consumer_key"] = "xxxxxxxxxxx";
    // .... setting required parameters
    param["oauth_version"] = "1.0";
    param["status"] = message;

    Uri uri;
    string query;
    Dictionary<HttpRequestHeader, string> headers;
    OAuth("https://api.twitter.com/statuses/update.json", "POST", param, out uri, out query, out headers);
    
    WebClient wc = new WebClient();
    foreach (var header in headers)
        wc.Headers[header.Key] = header.Value;
    wc.UploadStringCompleted += OnUploadStringCompleted;
    wc.UploadStringAsync(uri, query);
}

void OnUploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
    // Get Json formatted data by e.Result if e.Error equals NULL.
}




OAuth 1.0a is really harder to be implemented than OAuth 2.0, but this taught me a good lesson.

Thursday, February 10, 2011

WebClient by use of Rx ( Reactive Extensions ) for Silverlight.

I don't think the following code is good, but I wanted to check Rx ( Reactive Extensions ) about how it works.
Anyway, It's time for me to do "memo memo" here~.

Reactive Extensions for .NET (Rx)
http://msdn.microsoft.com/en-us/devlabs/ee794896


Preparation

    1. Download a msi file for Rx and then install it.
        ( See the above link for details )

    2. Add the following 3 Rx assemblies to the References in the target project. 
            System.CoreEx
            System.Observable
            System.Reactive





Sample

 public MainViewModel()
 {
   .
   .
   .
  var client = new WebClient();
  client.DownloadStringCompleted += Wc_DownloadStringCompleted;
  try
  {
   client.DownloadStringAsync(new Uri(<URL>, UriKind.Absolute));
  }
  catch(Exception ex)
  {
   MessageBox.Show(ex.Message);
  }
   .
   .
   .
 }

 void Wc_DownloadStringCompleted(object sender, 
                                 DownloadStringCompletedEventArgs e)
 {
   .
   .
   .
 } 

Reactive Extensions

 public MainViewModel()
 {
   .
   .
   .
  var client = new WebClient();
  Observable.FromEvent<DownloadStringCompletedEventHandler, 
                       DownloadStringCompletedEventArgs>(
        h => h.Invoke,
        h => client.DownloadStringCompleted += h,
        h => client.DownloadStringCompleted -= h)
   .Where(e => !e.EventArgs.Cancelled)
   .Retry(3)
   .SelectMany(
        e => (e.EventArgs.Error == null && !string.IsNullOrEmpty(e.EventArgs.Result))
                 ? Observable.Return(e.EventArgs)
                 : Observable.Throw<DownloadStringCompletedEventArgs>(e.EventArgs.Error))
   .Take(1)
   .Subscribe(
        s => Rx_DownloadStringCompleted(s.Result),
        e => MessageBox.Show(e.Message),
       () => { });


  Observable.Return(<URL>)
   .Where(u => !string.IsNullOrEmpty(u))
   .SelectMany(u => Observable.Return(new Uri(u, UriKind.Absolute)))
   .Subscribe(
        s => client.DownloadStringAsync(s),
        e => MessageBox.Show(e.Message),
       () => { });
   .
   .
   .
 }

 void Rx_DownloadStringCompleted(string result)
 {
   .
   .
   .
 } 


I applied Rx to Silverlight RSS Reader Application, and then, I was able to confirm that it worked as usual.


Very interesting~.

Wednesday, February 2, 2011

Silverlight RSS Reader ( Out Of Browser Version )

I posted Silverlight RSS Reader before, but that requires the proxy server to get RSS feeds.
( See Simple Silverlight RSS Reader. (MVVM Pattern) )
So I was wondering if I create the application with OOB(out of browser).

* Out-of-Browser Settings on Visual Studio
Check "Require elevated trust when running outside the browser".


* Install PFX file on the silverlight project.

1-1.Create a self-signed SSL certificate ( use for text, i.e. non trusted )

makecert.exe( Visual studio pro or windows sdk. )
http://msdn.microsoft.com/en-US/library/bfsktky3(v=VS.100).aspx


(1) Create a root certificate authority.
makecert -n "CN=Dummy Certificate Authority" -r -a sha1 -sr LocalMachine -sky signature -sv OOBRootCA.pvk OOBRootCA.cer

(2) Create a code-signing certificate.
makecert -sv OOBCodeSigningCA.pvk -iv OOBRootCA.pvk -n "CN=OOB Code Signing CA" -ic OOBRootCA.cer OOBCodeSigningCA.cer

(3) Convert the certificate and key to pfx file.
pvk2pfx -pvk OOBCodeSigningCA.pvk -spc OOBCodeSigningCA.cer -pfx DummyOOBCodeSigningCA.pfx -po <password>


1-2. Install the file on the project.

(1) In solution explorer, right-click the project name, and then click Properties. In the Properties Pages dialog box, click the Signing tab.
























(2) Click "Select from File" button and Select the pfx file.






















(3) Enter the password.














(4) Save Properties, then it's done.






* Coding Consideration on OOB

1. Check network status and Download itself if updated.

App.xaml.cs
public App()
{
   .
   .
   .
 NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;


        if (this.IsRunningOutOfBrowser)
            this.CheckAndDownloadUpdateCompleted += App_CheckAndDownloadUpdateCompleted;
   .
   .
   .

}

private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
    if (NetworkInterface.GetIsNetworkAvailable())
    {
        // something
    }
    else
    {
        // something
    }
}

private void App_CheckAndDownloadUpdateCompleted(
                     object sender,
                     CheckAndDownloadUpdateCompletedEventArgs e)
{
    if (e.UpdateAvailable)
    {
        MessageBox.Show("The update has been downloaded. Please restart the application.", 
                        "Application Update",MessageBoxButton.OK);
    }
}



2. Custom Windows Control bar for Silverlight OOB.

WindowControlBar.xaml
<UserControl x:Class="RSSReaderOOB.WindowControlBar"
    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"
    mc:Ignorable="d"
    d:DesignHeight="26" d:DesignWidth="300">

    <Grid Background="LightGray" Height="26" MaxHeight="26" MinHeight="26">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        <Image x:Name="IconImage" Source="/Images/IconSL16.png" Width="16" Height="16" Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3,0,0,0" />
        <TextBlock x:Name="TitleTextBlock" Margin="22,0,0,0" FontSize="13" Text="Silverlight OOB Application" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" />
        <StackPanel x:Name="WindowControlBarRoot" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Top"
                        Margin="0,0,0,0" HorizontalAlignment="Right">
            <Canvas Width="30" x:Name="wcbMinimizeButton" Cursor="Hand" Background="#00000000"
                        Visibility="Visible" Height="20" ToolTipService.ToolTip="Minimize">
                <Border Width="30" Height="20" Background="#FF939393" BorderBrush="#FF000000"
                            BorderThickness="1,1,0,1" CornerRadius="0,0,0,5">
                    <Border BorderThickness="1.5,1.5,1.5,1.5" CornerRadius="0,0,0,5">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.514,0.623"
                                                     StartPoint="0.514,0.191">
                                <GradientStop Color="#FF828282" Offset="0"/>
                                <GradientStop Color="#FF262626" Offset="1"/>
                            </LinearGradientBrush>
                        </Border.Background>
                        <Rectangle Margin="6,9,6,3" Fill="#FFD6D5D5" Stroke="#FF000000"
                                       StrokeThickness="0.5"/>
                    </Border>
                </Border>
            </Canvas>
            <Canvas Width="30" x:Name="wcbMaximizeButton" Cursor="Hand" Background="#00000000"
                        Visibility="Visible" Height="20" ToolTipService.ToolTip="Maximize">
                <Border Width="30" Height="20" Background="#FF939393" BorderBrush="#FF000000"
                            BorderThickness="1,1,0,1">
                    <Border BorderThickness="1.5,1.5,1.5,1.5" CornerRadius="0,0,0,0" Width="29"
                                Height="18">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.514,0.623"
                                                     StartPoint="0.514,0.191">
                                <GradientStop Color="#FF828282" Offset="0"/>
                                <GradientStop Color="#FF262626" Offset="1"/>
                            </LinearGradientBrush>
                        </Border.Background>
                        <Border Background="#FFD6D5D5" Margin="6,2,6,2" BorderBrush="#FF000000"
                                    BorderThickness="0.5,0.5,0.5,0.5">
                            <Rectangle Stroke="#FF000000" Margin="2,2,2,2"
                                           StrokeThickness="0.5">
                                <Rectangle.Fill>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="#FF828282" Offset="0"/>
                                        <GradientStop Color="#FF262626" Offset="1"/>
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                        </Border>
                    </Border>
                </Border>
            </Canvas>
            <Canvas Width="40" x:Name="wcbCloseButton" Cursor="Hand" Background="#00000000"
                        Opacity="1" Height="20" ToolTipService.ToolTip="Close">
                <Border Width="40" Height="20" Background="#FF939393" BorderBrush="#FF000000"
                            BorderThickness="1,1,1,1" CornerRadius="0,0,5,0">
                    <Border BorderThickness="1,1,1,1" CornerRadius="0,0,5,0" Width="37"
                                Height="16" x:Name="border">
                        <Border.Background>
                            <LinearGradientBrush EndPoint="0.514,0.623"
                                                     StartPoint="0.514,0.191">
                                <GradientStop Color="#FF956161" Offset="0"/>
                                <GradientStop Color="#FF490E0E" Offset="1"/>
                            </LinearGradientBrush>
                        </Border.Background>
                        <TextBlock Text="X" TextWrapping="Wrap" Foreground="#FFECECEC"
                                       HorizontalAlignment="Center" VerticalAlignment="Center"
                                       x:Name="textBlock"/>
                    </Border>
                </Border>
            </Canvas>
        </StackPanel>

    </Grid>
</UserControl>

WindowControlBar.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace RSSReaderOOB
{
    public partial class WindowControlBar : UserControl
    {
        public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(WindowControlBar), new PropertyMetadata(OnTitleChanged));
        public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(Uri), typeof(WindowControlBar), new PropertyMetadata(OnIconChanged));

        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }

        public Uri Icon
        {
            get { return (Uri)GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }

        private static void OnTitleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                string newTitle = e.NewValue as string;
                WindowControlBar wcb = sender as WindowControlBar;
                wcb.TitleTextBlock.Text = newTitle;
            }
        }

        private static void OnIconChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                if (e.NewValue is Uri)
                {
                    WindowControlBar wcb = sender as WindowControlBar;
                    wcb.IconImage.Source = new System.Windows.Media.Imaging.BitmapImage(e.NewValue as Uri);
                }
            }
        }

        public WindowControlBar()
        {
            InitializeComponent();
            if (Application.Current.IsRunningOutOfBrowser)
            {
                this.Visibility = Visibility.Visible;
                this.wcbMaximizeButton.MouseLeftButtonDown += new MouseButtonEventHandler(wcbMaximizeButton_MouseLeftButtonDown);
                this.wcbMinimizeButton.MouseLeftButtonDown += new MouseButtonEventHandler(wcbMinimizeButton_MouseLeftButtonDown);
                this.wcbCloseButton.MouseLeftButtonDown += new MouseButtonEventHandler(wcbCloseButton_MouseLeftButtonDown);
                this.MouseLeftButtonDown += new MouseButtonEventHandler(WindowControlBar_MouseLeftButtonDown);
            }
            else
                this.Visibility = Visibility.Collapsed;
        }

        void WindowControlBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Application.Current.MainWindow.DragMove();
        }

        void wcbCloseButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Application.Current.MainWindow.Close();
        }

        void wcbMinimizeButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Application.Current.MainWindow.WindowState = WindowState.Minimized;
        }

        void wcbMaximizeButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (Application.Current.MainWindow.WindowState == WindowState.Normal)
                Application.Current.MainWindow.WindowState = WindowState.Maximized;
            else
                Application.Current.MainWindow.WindowState = WindowState.Normal;
        }
    }
}


Here are the capture images of the application.

1.Start the application and then click Install button.
The Application on the browser.




















2.Click Install button.
* Security Warning appears because of Non-Trusted SSL.




















3.Enter a RSS feed url in the textbox.


















4. Done.




Sunday, August 29, 2010

Simple Silverlight RSS Reader. (MVVM Pattern)

As a little more useful application under MVVM Pattern, I created a silverlight RSS reader.

Silverlight RSS Reader Demo
http://demo.gehintleman.com/RssReader.html


But, as is well known, silverlight application throws System.Security.SecurityException unless the target host has a clientaccesspolicy.xml.
(Because silverlight does not allow corss domain access.)

One of the solution against that, using GAE(Google App Engine) is a workable alternative.

1.Create rssfeed.py

# -*- coding: utf-8 -*-
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch

class GetRssFeed(webapp.RequestHandler):
  def get(self):
    u = self.request.get("u")
    if u:
      try:
        result = urlfetch.fetch(u)
        self.response.out.write(result.content)
      except:
        self.error(404)
    else:
      self.error(404)


application = webapp.WSGIApplication([('/RssFeed',GetRssFeed)], debug=False)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()


2. Create clientaccesspolicy.xml

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from>
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>


3. Add the following configurations in app.yaml

- url: /RssFeed
  script: rssfeed.py
- url: /clientaccesspolicy.xml
  static_files: clientaccesspolicy.xml
  upload: clientaccesspolicy.xml


After deploying those files to GAE, silverlight applications can fetch RSS via the python script.

http://<your application name>.appspot.com/RssFeed?u=<target RSS feed url>


* Actually, I didn't use Expression Blend to create the view. so it doesn't look good.
   but, I think, trying to code xaml must be good to deeply understand silverlight.

Wednesday, August 18, 2010

MVVM Pattern for Silverlight 4

I tried creating a simple silverlight application under some of MVVM pattern rules like followings.

・Views can do "CRUD" data only by "Data Binding" from ViewModels. ( CRUD : Create, Read, Update, Delete )
・Any events will be executed on ViewModels by "ICommand" from Views or some Behaviors on Views.
    (which means there is no code behind on the view.)

⇒ "loose coupling" between a view and a viewmodel ( ViewとViewModelの疎結合 )


MVVM Pattern for Silverlight 4  Demo
http://demo.gehintleman.com/MVVMPattern.html

・There are 4 Views (including MainView), and all the Views do not have any code behinds.
・Views and ViewModels are managed through ExportAttribute/ImportAttribute.
・Using resource files(*.resx) for the localization.


MVVM Pattern could clearly devide web application development into coding by programmers and designing by designers.

* Differently from WPF, Silverlight cannot assign(bind) ViewModels to Views in Application.Resources in APP.XAML.
   But, Managed Extensibility Framework ( a.k.a. MEF ) is so great that we can easily manage ViewModels and Views.

Sunday, July 18, 2010

Authentication in silverlight 4

Here is a preparation for Very Very Verrrrry simple Login System for Silverlight.


I. Server Side ( XXXXX.Web project )

1. Membership Provider class

namespace XXXXX.Web.Providers
{
    public class CustomMembershipProvider : MembershipProvider
    {
        public override string ApplicationName { set; get; }
        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            return new MembershipUser("CustomMembershipProvider",
                username,
                null,
                null,
                null,
                null,
                false,
                false,
                new DateTime(),
                new DateTime(),
                new DateTime(),
                new DateTime(),
                new DateTime());
        }

        public override bool ValidateUser(string username, string password)
        {
            if(username == "admin")
                return password == "password";
            if(username == "user")
                return password == "password";
            return false;
        }

        public override bool EnablePasswordReset { get { throw new NotImplementedException(); } }

        public override bool EnablePasswordRetrieval { get { throw new NotImplementedException(); } }

        public override bool RequiresQuestionAndAnswer { get { throw new NotImplementedException(); } }

        public override int MaxInvalidPasswordAttempts { get { throw new NotImplementedException(); } }

        public override int PasswordAttemptWindow { get { throw new NotImplementedException(); } }

        public override bool RequiresUniqueEmail { get { throw new NotImplementedException(); } }

        public override MembershipPasswordFormat PasswordFormat { get { throw new NotImplementedException(); } }

        public override int MinRequiredPasswordLength { get { throw new NotImplementedException(); } }

        public override int MinRequiredNonAlphanumericCharacters { get { throw new NotImplementedException(); } }

        public override string PasswordStrengthRegularExpression { get { throw new NotImplementedException(); } }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { throw new NotImplementedException(); }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { throw new NotImplementedException(); }

        public override string GetPassword(string username, string answer) { throw new NotImplementedException(); }

        public override bool ChangePassword(string username, string oldPassword, string newPassword) { throw new NotImplementedException(); }

        public override string ResetPassword(string username, string answer) { throw new NotImplementedException(); }

        public override void UpdateUser(MembershipUser user) { throw new NotImplementedException(); }

        public override bool UnlockUser(string userName) { throw new NotImplementedException(); }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) { throw new NotImplementedException(); }

        public override string GetUserNameByEmail(string email) { throw new NotImplementedException(); }

        public override bool DeleteUser(string username, bool deleteAllRelatedData) { throw new NotImplementedException(); }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }

        public override int GetNumberOfUsersOnline() { throw new NotImplementedException(); }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
    }
}


2. Profile Provider class

namespace XXXXX.Web.Providers
{
    public class CustomProfileProvider : ProfileProvider
    {
        public override string ApplicationName { set; get; }

        public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
        {
            var username = context["UserName"];
            var result = new SettingsPropertyValueCollection();

            result.Add(new SettingsPropertyValue(
                new SettingsProperty(
                    "WelcomeMessage",
                    typeof(string),
                    null,
                    true,
                    string.Format("ようこそ {0}さん", username),
                    SettingsSerializeAs.String,
                    null,
                    false,
                    false)));
            return result;
        }

        public override int DeleteProfiles(ProfileInfoCollection profiles) { throw new NotImplementedException(); }

        public override int DeleteProfiles(string[] usernames) { throw new NotImplementedException(); }

        public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { throw new NotImplementedException(); }

        public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) { throw new NotImplementedException(); }

        public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }

        public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }

        public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }

        public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }

        public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) { throw new NotImplementedException(); }
    }
}


3. Role Provider class

namespace XXXXX.Web.Providers
{
    public class CustomRoleProvider : RoleProvider
    {
        public override string ApplicationName { set; get; }

        public override string[] GetRolesForUser(string username)
        {
            if (username == "admin")
                return new[] { "Administrators", "Users" };
            if (username == "user")
                return new[] { "Users" };
            return null;
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            if(username == "admin")
                return roleName == "Administrators" || roleName == "Users";
            if(username == "user")
                return roleName == "Users";
            return false;
        }

        public override void CreateRole(string roleName) { throw new NotImplementedException(); }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { throw new NotImplementedException(); }

        public override bool RoleExists(string roleName) { throw new NotImplementedException(); }

        public override void AddUsersToRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { throw new NotImplementedException(); }

        public override string[] GetUsersInRole(string roleName) { throw new NotImplementedException(); }

        public override string[] GetAllRoles() { throw new NotImplementedException(); }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch) { throw new NotImplementedException(); }
    }
}


4. User class

namespace XXXXX.Web.Providers
{
    public class User : UserBase
    {
        public string WelcomeMessage { set; get; }
    }
}


5. Authentication Domain Service class

    [EnableClientAccess]
    public class AuthenticationService : AuthenticationBase<User> { }


6. Web.Config

  <system.web>
    <authentication mode="Forms" />
    <membership defaultProvider="customProvider">
      <providers>
        <clear />
        <add name="customProvider" type="XXXXX.Web.Providers.CustomMembershipProvider"/>
      </providers>
    </membership>
    <profile enabled="true" defaultProvider="customProvider">
      <properties>
        <add name="WelcomeMessage" allowAnonymous="false"/>
      </properties>
      <providers>
        <clear />
        <add name="customProvider" type="XXXXX.Web.Providers.CustomProfileProvider"/>
      </providers>
    </profile>
    <roleManager enabled="true" defaultProvider="customProvider">
      <providers>
        <clear />
        <add name="customProvider" type="XXXXX.Web.Providers.CustomRoleProvider"/>
      </providers>
    </roleManager>
  </system.web>



II. Client side ( XXXXX project )

7. App.xaml.cs

        public App()
        {
            this.Startup += this.Application_Startup;
            this.Exit += this.Application_Exit;
            this.UnhandledException += this.Application_UnhandledException;

            InitializeComponent();

            WebContext webcontext = new WebContext();
            webcontext.Authentication = new FormsAuthentication();
            this.ApplicationLifetimeObjects.Add(webcontext);
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            this.Resources.Add("WebContext", WebContext.Current);
            //this.RootVisual = new MainPage();
            this.RootVisual = new BasePage();
        }


Here is the pages for the simple login system.

8. BasePage.xaml

<UserControl x:Class="XXXXX.BasePage"
    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"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

</UserControl>


9.BasePage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace XXXXX
{
    using XXXXX.Web;

    public partial class BasePage : UserControl
    {
        public BasePage()
        {
            InitializeComponent();
            if (this.Content == null)
            {
                this.Content = new LoginPage();
            }
            else
            {
                var user = WebContext.Current.User;
                if (user.IsAuthenticated)
                    ((BasePage)Parent).ShowMainPage();
                else
                    ((BasePage)Parent).ShowLoginPage();
            }
        }

        public void ShowLoginPage()
        {
            this.Content = new LoginPage();
        }

        public void ShowMainPage()
        {
            this.Content = new MainPage();
        }
    }
}



** [IMPORTANT] **

10. MainPage.xaml.cs

add following code in the constructor.

var user = WebContext.Current.User;
if (!user.IsAuthenticated)
    ((BasePage)Parent).ShowLoginPage();




I know that using "business application template" is easier than the above way, but I hope it would be more customizable.

Wednesday, February 24, 2010

Adding Watermark to TextBox in Silverlight 3

It's very easy to add watermark to TextBox in Silverlight.



I haven't usually posted any codes, but I do today ... against my being lazy. 今回は何となくコード載せてみます。。。

C# Code:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Custom.Silverlight.Controls
{
public class WatermarkedTextBox : TextBox
{
public WatermarkedTextBox()
: base()
{
this.NormalBackground = new SolidColorBrush(Colors.White);
this.NormalForeground = new SolidColorBrush(Colors.Black);
this.WatermarkBackground = new SolidColorBrush(Colors.White);
this.WatermarkForeground = new SolidColorBrush(Colors.Gray);
this.Watermark = "Please enter text here...";
}

private DependencyProperty WatermarkProperty =
 DependencyProperty.Register("Watermark", typeof(object), typeof(WatermarkedTextBox)
              , new PropertyMetadata(OnWatermarkChanged));
private DependencyProperty WatermarkBackgroundProperty =
 DependencyProperty.Register("WatermarkBackground", typeof(Brush), typeof(WatermarkedTextBox)
              , new PropertyMetadata(OnWatermarkBackgroundChanged));
private DependencyProperty WatermarkForegroundProperty =
 DependencyProperty.Register("WatermarkForeground", typeof(Brush), typeof(WatermarkedTextBox)
              , new PropertyMetadata(OnWatermarkForegroundChanged));
private DependencyProperty NormalBackgroundProperty =
 DependencyProperty.Register("NormalBackground", typeof(Brush), typeof(WatermarkedTextBox)
              , new PropertyMetadata(OnNormalBackgroundChanged));
private DependencyProperty NormalForegroundProperty =
 DependencyProperty.Register("NormalForeground", typeof(Brush), typeof(WatermarkedTextBox)
              , new PropertyMetadata(OnNormalForegroundChanged));
private DependencyProperty ToolTipProperty =
 DependencyProperty.Register("ToolTip", typeof(object), typeof(WatermarkedTextBox)
              , new PropertyMetadata(OnToolTipChanged));

private static void OnWatermarkChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}

private static void OnWatermarkBackgroundChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}

private static void OnWatermarkForegroundChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}

private static void OnNormalBackgroundChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}

private static void OnNormalForegroundChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}


private static void OnToolTipChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}


public string Watermark
{
get { return (string)GetValue(WatermarkProperty); }
set
{
SetValue(WatermarkProperty, value);
base.Text = value;
}
}

public Brush WatermarkBackground
{
get { return (Brush)GetValue(WatermarkBackgroundProperty); }
set
{
SetValue(WatermarkBackgroundProperty, value);
base.Background = value;
}
}

public Brush WatermarkForeground
{
get { return (Brush)GetValue(WatermarkForegroundProperty); }
set
{
SetValue(WatermarkForegroundProperty, value);
base.Foreground = value;
}
}public Brush NormalBackground
{
get { return (Brush)GetValue(NormalBackgroundProperty); }
set
{
SetValue(NormalBackgroundProperty, value);
}
}

public Brush NormalForeground
{
get { return (Brush)GetValue(NormalForegroundProperty); }
set
{
SetValue(NormalForegroundProperty, value);
}
}

public string ToolTip
{
get { return (string)GetValue(ToolTipProperty); }
set
{
SetValue(ToolTipProperty, value);
ToolTipService.SetToolTip(this, value);
            }
}



public new Brush Background { set; get; }
public new Brush Foreground { set; get; }

public new string Text
{
set
{
base.Text = value;
}
get
{
if (Watermark == base.Text)
return null;
return base.Text;
}
}

protected override void OnGotFocus(RoutedEventArgs e)
{
base.Background = this.NormalBackground;
base.Foreground = this.NormalForeground;

if (base.Text == Watermark)
base.Text = "";
base.OnGotFocus(e);
}

protected override void OnLostFocus(RoutedEventArgs e)
{
if (String.IsNullOrEmpty(base.Text) || base.Text == Watermark)
{
base.Text = Watermark;
base.Background = WatermarkBackground;
base.Foreground = WatermarkForeground;
}
base.OnLostFocus(e);
}

}
}

XAML:
          <controls:WatermarkedTextBox   x:Name="XXXXXX" 
                                           Watermark="テキストを入力してください。"
                                           ToolTip="テキストを入力してください。"

                                           WatermarkBackground="#FFFFFF00" 
                                           WatermarkForeground="#FFFF0000" /> 
* xmlns:controls="clr-namespace:Custom.Silverlight.Controls"


Well, I even tried creating another controls like the watermarkedTextBox, such as WatermarkedComboBox, MaskedTextBox, NumericMaskedTextBox, DateTimeMaskedTextBox in "Silverlight 4 Beta".






コード載せるのめんどくせぇ~~~ >_<

Sunday, February 7, 2010

Simple RichText Editor by Silverlight 4 (Beta)

Silverlight 4 is more powerful than the version 3, and we can easily implement rich contents by use of it.
One of them, there's RichTextArea ( mostly similar to RichTextBox in WPF ).
and New MouseButtonHandlers (MouseRightButtonDown and MouseRightButtonUp) is going to be supported (Silverlight 4 or later).
So a ContextMenu can be implemented.



1. ContextMenu


2. Font Size


3. Color Selector


4. Insert Hyperlink


Sample


after releasing Silverlight 4, we can upload richtext for comments on Blog or somewhere like forum sites by silverlight application.
by use of sort of following format.

Thursday, December 17, 2009

Out of Browser

It's not easy to find out the best practice about "Out Of Browser", but as one of solutions on the Internet,
Online Catalog or something like that would be nice... I think.
Because the catalog always provides the latest information whenever we start the "Out of browser", differently from PDF or Word files.

Demo site ( Until Dec 31, 2009 )
http://lol.cloudapp.net/SilverlightCatalog.aspx


1. Silverlight Page







2. Installing Out of Browser



3. Starting Out of Browser







4. Starting Out of Browser when Network is not available



Adding "Out of Browser" on Silverlight is very easy, but not easy to add what kind of service on it ... as usual.