カテゴリー別アーカイブ: Silverlight

【Silverlight】 コンテキストメニューを表示するには

◆ 事前準備

1. Silverlight Toolkit をインストール
  ★NuGet
    http://nuget.org/List/Packages/SilverlightToolkit-All    
  ★インストーラー
    http://silverlight.codeplex.com/releases/view/43528

2. System.Windows.Controls.Input.Toolkit.dll を参照設定

◆ XAML

<UserControl x:Class="Views.TestView"
  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:controlsInputToolkit="clr-namespace:System.Windows.Controls;
    assembly=System.Windows.Controls.Input.Toolkit"
  mc:Ignorable="d"
  d:DesignHeight="300" d:DesignWidth="400">
  
  <Grid x:Name="LayoutRoot">
    <StackPanel HorizontalAlignment="Left">
      <TextBox Name="txtContextMenu" Height="30" Width="200">
        <controlsInputToolkit:ContextMenuService.ContextMenu>
          <controlsInputToolkit:ContextMenu Height="90" 
              Name="contextMenu1" Width="160">
            <controlsInputToolkit:MenuItem x:Name="MenuCopy"
                Header="コピー" Click="MenuCopy_Click">
              <controlsInputToolkit:MenuItem.Icon>
                <Image Height="25" Width="25" Source="Copy.png"></Image>
              </controlsInputToolkit:MenuItem.Icon>
            </controlsInputToolkit:MenuItem>
            <controlsInputToolkit:MenuItem x:Name="MenuPaste" 
                Header="貼り付け" Click="MenuPaste_Click">
              <controlsInputToolkit:MenuItem.Icon>
                <Image Height="25" Width="25" Source="Paste.png"></Image>
              </controlsInputToolkit:MenuItem.Icon>
            </controlsInputToolkit:MenuItem>
            <controlsInputToolkit:Separator />
            <controlsInputToolkit:MenuItem x:Name="MenuCut" 
                Header="切り取り" Click="MenuCut_Click">
              <controlsInputToolkit:MenuItem.Icon>
                <Image Height="25" Width="25" Source="Cut.png"></Image>
              </controlsInputToolkit:MenuItem.Icon>
            </controlsInputToolkit:MenuItem>
          </controlsInputToolkit:ContextMenu>
        </controlsInputToolkit:ContextMenuService.ContextMenu>
      </TextBox>      
    </StackPanel>    
  </Grid>
</UserControl>

◆ C# Code

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Views
{
    public partial class TestView : UserControl
    {
        public TestView()
        {
            InitializeComponent();

            this.MouseRightButtonDown += (s, e) =>
            {
                e.Handled = true;
            };
        }

        // コピー
        private void MenuCopy_Click(object sender, RoutedEventArgs e)
        {
            Clipboard.SetText(this.txtContextMenu.Text);
        }

        // 貼り付け
        private void MenuPaste_Click(object sender, RoutedEventArgs e)
        {
            this.txtContextMenu.Text = Clipboard.GetText();
        }

        // 切り取り
        private void MenuCut_Click(object sender, RoutedEventArgs e)
        {
            Clipboard.SetText(this.txtContextMenu.Text);
            this.txtContextMenu.Text = string.Empty;
        }
    }
}

広告

【Silverlight】 DataGrid に グループを設定するには

◆ XAML

<UserControl x:Class="Views.GroupView "
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                <Button Name="btnSetGroup" Click="btnSetGroup_Click" 
                    Content="グループ設定" Height="30" Width="140"></Button>
                <Button Name="btnClearGroup" Click="btnClearGroup_Click" 
                    Content="グループ解除" Height="30" Width="140"></Button>
            </StackPanel>
            <TextBlock Height="10" />
            <sdk:DataGrid Name="dataGrid1" Width="300" Height="300" 
                IsReadOnly="True" AutoGenerateColumns="True"
                HorizontalAlignment="Left"/>
        </StackPanel>
    </Grid>
</UserControl>

◆ C# Code

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace Views
{
    public partial class GroupView : UserControl
    {
        public GroupView()
        {
            InitializeComponent();
        }

        // DataGird表示用エンティティ
        public class User
        {
            public string name { get; set; }
            public int age { get; set; }            
        }

        // グループ設定 イベント
        private void btnSetGroup_Click(object sender, RoutedEventArgs e)
        {
            // データ
            User[] userArray = {
                        new User { name="Taro", age=20},
                        new User { name="Jiro", age=25},
                        new User { name="Saburo", age=30},
                        new User { name="Shiro", age=35},
                        new User { name="Goro", age=40},
                        new User { name="Rokuro", age=20},
                        new User { name="Nanaro", age=40},
                        new User { name="Hachiro", age=40},
                    };

            // PagedCollectionView へ変換してセット
            this.dataGrid1.ItemsSource = new PagedCollectionView(userArray);

            // グループ設定
            var pcv = this.dataGrid1.ItemsSource as PagedCollectionView;
            if (pcv != null && pcv.CanGroup == true)
            {
                // グループ条件
                pcv.GroupDescriptions.Add(
                    new PropertyGroupDescription("age"));
            }
        }

        // グループ解除 イベント
        private void btnClearGroup_Click(object sender, RoutedEventArgs e)
        {
            // グループ解除
            var pcv = this.dataGrid1.ItemsSource as PagedCollectionView;
            if (pcv != null)
            {
                pcv.GroupDescriptions.Clear();
            }
        }
    }
}

【Silverlight】 DataGrid に ソートを設定するには

◆ XAML

<UserControl x:Class="Views.SortView "
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                <Button Name="btnSetSort" Click="btnSetSort_Click" 
                    Content="ソート設定" Height="30" Width="120"></Button>
                <Button Name="btnClearSort" Click="btnClearSort_Click" 
                    Content="ソート解除" Height="30" Width="120"></Button>
            </StackPanel>
            <TextBlock Height="10" />
            <sdk:DataGrid Name="dataGrid1" Width="300" Height="300" 
                IsReadOnly="True" AutoGenerateColumns="True"
                HorizontalAlignment="Left"/>
        </StackPanel>
    </Grid>
</UserControl>

◆ C# Code

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.ComponentModel;

namespace Views
{
    public partial class SortView : UserControl
    {
        public SortView()
        {
            InitializeComponent();
        }

        // DataGird表示用エンティティ
        public class User
        {
            public string name { get; set; }
            public int age { get; set; }            
        }

        // ソート設定 イベント
        private void btnSetSort_Click(object sender, RoutedEventArgs e)
        {
            // データ
            User[] userArray = {
                        new User { name="Taro", age=20},
                        new User { name="Jiro", age=25},
                        new User { name="Saburo", age=30},
                        new User { name="Shiro", age=35},
                        new User { name="Goro", age=40},
                    };

            // PagedCollectionView へ変換してセット
            this.dataGrid1.ItemsSource = new PagedCollectionView(userArray);

            // ソート設定
            var pcv = this.dataGrid1.ItemsSource as PagedCollectionView;
            if (pcv != null && pcv.CanSort == true)
            {
                // ソート条件
                pcv.SortDescriptions.Add(
                  new SortDescription("name", ListSortDirection.Ascending));
            }
        }

        // ソート解除 イベント
        private void btnClearSort_Click(object sender, RoutedEventArgs e)
        {
            // ソート解除
            var pcv = this.dataGrid1.ItemsSource as PagedCollectionView;
            if (pcv != null)
            {
                pcv.SortDescriptions.Clear();
            }
        }
    }
}

【Silverlight】 DataGrid に フィルターを設定するには

◆ XAML

<UserControl x:Class="Views.FilterView "
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                <Button Name="btnSetFilter" Click="btnSetFilter_Click" 
                    Content="フィルター設定" Height="30" Width="140"></Button>
                <Button Name="btnClearFilter" Click="btnClearFilter_Click" 
                    Content="フィルター解除" Height="30" Width="140"></Button>
            </StackPanel>
            <TextBlock Height="10" />
            <sdk:DataGrid Name="dataGrid1" Width="300" Height="300" 
                IsReadOnly="True" AutoGenerateColumns="True"
                HorizontalAlignment="Left"/>
        </StackPanel>
    </Grid>
</UserControl>

◆ C# Code

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace Views
{
    public partial class FilterView : UserControl
    {
        public FilterView()
        {
            InitializeComponent();
        }

        // DataGird表示用エンティティ
        public class User
        {
            public string name { get; set; }
            public int age { get; set; }            
        }

        // フィルター設定 イベント
        private void btnSetFilter_Click(object sender, RoutedEventArgs e)
        {
            // データ
            User[] userArray = {
                        new User { name="Taro", age=20},
                        new User { name="Jiro", age=25},
                        new User { name="Saburo", age=30},
                        new User { name="Shiro", age=35},
                        new User { name="Goro", age=40},
                    };

            // PagedCollectionView へ変換してセット
            this.dataGrid1.ItemsSource = new PagedCollectionView(userArray);

            // フィルター設定
            var pcv = this.dataGrid1.ItemsSource as PagedCollectionView;
            if (pcv != null && pcv.CanFilter == true)
            {
                // フィルター条件
                pcv.Filter = (o) => (o as User).age >= 30);
            }
        }

        // フィルター解除 イベント
        private void btnClearFilter_Click(object sender, RoutedEventArgs e)
        {
            // フィルター解除
            var pcv = this.dataGrid1.ItemsSource as PagedCollectionView;
            if (pcv != null)
            {
                pcv.Filter = null;
            }
        }
    }
}

【Silverlight】 ログイン認証で、WCF RIA Servicesの利用制限を行うには

◆ 認証機能は、前回のログイン認証を利用

using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;

namespace Web.Services.LoginService
{
    [EnableClientAccess()]
    public class LoginTestService : DomainServiceBase
    {
        // RequiresAuthentication属性を適用した場合、
        // 認証済みユーザーのみアクセス可能となる。
        [RequiresAuthentication()]
        public IQueryable<Uma> GetUmas()
        {
            return base.GetQuery<Uma>();
        }

        // RequiresRole属性を適用した場合、
        // ロールに所属するユーザーのみアクセス可能となる。
        [RequiresRole("Administrator")]
        public void UpdateUma(Uma entity)
        {
            base.UpdateQuery<Uma>(entity);
        }
    }
}

【Silverlight】 WCF RIA Servicesを使用して、ログイン認証を行うには

◆ ログイン検証 プロバイダー

using System;
using System.Web.Security;

namespace Web.Services.LoginService
{
    public class CustomMembershipProvider : MembershipProvider
    {
        // ログイン検証
        public override bool ValidateUser(string username, string password)
        {
            // 今回は、ユーザー名とパスワードが一致したら認証OKとする。
            return (username.Equals(password));                
        }

        public override MembershipUser GetUser
            (string username, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        // 今回、以下 override は同様にNotImplementedException を実装
        // ・・・
    }
}

◆ ロール設定 プロバイダー

using System;
using System.Web.Security;

namespace Web.Services.LoginService
{
    public class CustomRoleProvider : RoleProvider
    {
        // ユーザーに対するロールを設定
        public override string[] GetRolesForUser(string username)
        {
            // 今回は、ユーザー名が admin であれば管理者とする。
            if (username.Equals("admin") )
            {
                return new string[] { "Administrator" };
            }
            else
            {
                return new string[] { "Gest" };
            }
        }

        public override string[] FindUsersInRole
            (string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }
        
        // 今回、以下 override は同様にNotImplementedException を実装
        // ・・・
    }
}

◆ Web.config

<system.web>
    // ・・・省略    
    <!-- Form認証 -->
    <authentication mode="Forms" />
    <!-- プロバイダー情報 -->
    <membership defaultProvider="customProvider">
      <providers>
        <add name="customProvider" 
            type=" Web.Services.LoginService.CustomMembershipProvider" />
      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="customProvider">
      <providers>
        <add name="customProvider" 
            type=" Web.Services.LoginService.CustomRoleProvider"/>
      </providers>
    </roleManager>    
</system.web>
  

◆ ユーザー エンティティ

using System.ServiceModel.DomainServices.Server.ApplicationServices;

namespace Web.Services.LoginService
{
    public class CustomUser : UserBase
    {
        // プロパティを実装する。今回は未実装。
    }
}

◆ ログイン認証 WCF RIA Services

using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server.ApplicationServices;

namespace Web.Services.LoginService
{
    [EnableClientAccess]
    public class LoginService : AuthenticationBase<CustomUser>
    {

    }
}

◆ Silverlight

// ログイン認証 WCF RIA Services の呼び出し
var context = new LoginContext();
context.Load(context.LoginQuery(loginId, password, true, null),
    result =>
    {
        if (result.HasError)
        {
            // ログイン エラー
            IsLogin = false;
        }
        else
        {
            // ログイン ユーザーを取得
            var user = result.Entities.FirstOrDefault();
            // user が null の場合は、認証NG
            IsLogin = (user == null ? false : true);
        }                    
    }, null);
    

【Silverlight】 WCF RIA Services(DbDomainService) のCRUD基底クラスを作成するには(ジェネリック・メソッドの場合)

◆ WCF RIA Services(DbDomainService) のCRUD基底クラス

using System.Linq;
using System.Data;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.ServiceModel.DomainServices.EntityFramework;
using System.Data.Entity.Infrastructure;

namespace Web.Services
{
    // CRUDドメインサービス基底クラス
    public abstract class DomainServiceCrud : DbDomainService<RaceContext>
    {
        // 読取
        protected virtual IQueryable<T> GetQuery<T>()
            where T : class
        {
            return this.DbContext.Set<T>();
        }

        // 更新
        protected virtual void UpdateQuery<T>(T entity)
            where T : class
        {
            var original = this.ChangeSet.GetOriginal(entity);

            if (original != null)
            {
                this.DbContext.Set<T>().AttachAsModified<T>(
                    entity, original, this.DbContext);
            }
            else
            {
                this.DbContext.Set<T>().Attach(entity);
            }
        }

        // 生成
        protected virtual void InsertQuery<T>(T entity)
            where T : class
        {            
            DbEntityEntry<T> entityEntry = this.DbContext.Entry<T>(entity);

            if (entityEntry.State != EntityState.Detached)
            {
                entityEntry.State = EntityState.Added;
            }
            else
            {
                this.DbContext.Set<T>().Add(entity);
            }
        }

        // 削除
        protected virtual void DeleteQuery<T>(T entity)
            where T : class
        {
            DbEntityEntry<T> entityEntry = this.DbContext.Entry<T>(entity);

            if (entityEntry.State != EntityState.Deleted)
            {
                entityEntry.State = EntityState.Deleted;
            }
            else
            {
                this.DbContext.Set<T>().Attach(entity);
                this.DbContext.Set<T>().Remove(entity);
            }
        }
    }
}

◆ 使用例

using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;

namespace Web.Services
{
    [EnableClientAccess()]
    public class CrudService : DomainServiceCrud
    {
        // 読取
        [Query]
        public IQueryable<Race> GetRaces()
        {
            return base.GetQuery<Race>();
        }

        // 更新
        [Update]
        public void UpdateRace(Race entity)
        {
            base.UpdateQuery<Race>(entity);
        }

        // 生成
        [Insert]
        public void InsertRace(Race entity)
        {
            base.InsertQuery<Race>(entity);
        }

        // 削除
        [Delete]
        public void DeleteRace(Race entity)
        {
            base.DeleteQuery<Race>(entity);
        }
    }
}