2016年02月01日

作って覚えるVisual C# 2015 デスクトップアプリ入門


Visual Studioのインストール手順から始まり、クラスやメソッドといった基本的な概念やオブジェクト指向といった用語の解説から始まり、簡単なアプリケーションの実装までを懇切丁寧に説明されています。

C#以外でもプログラミング経験のない人でも無理なく理解できるように書かれています。C#入門ではありますが、プログラミング入門でもあります。

従って、例えばJavaやC++の経験あるがC#が初めてなんて人が読むにはちょっと簡単すぎるかもしれません。

若しくは、基本的な文法やライブラリは一通り触ってみたが、イマイチ理解に及んでないような方には復讐を兼ねて一読するのも適当かもしれない。

posted by RR at 00:47 | Comment(0) | 書籍 | このブログの読者になる | 更新情報をチェックする

2016年02月21日

色の名前と実際の色とをWPFで表示する

画面イメージ
ColorNames.png


概要
背景色や文字色などは色の名前で指定できるが、馴染みのない単語なので実際の色がイメージしずらい。
実際の色と色の名前とを表示させるコード例。

解説
画面に表示させる色は光の三原色である赤(Red)・緑(Green)・青(Blue)の割合で決める。
各色を0から255の256段階で指定するので256の3乗で16,777,216色表現できる。
これに透明度を表すアルファ値(Alpha)とを合わせたのがRGBA。
これらの色の中で140色ほどに名前が着いてる。X11とかいう規格らしいのだが、必ずしも統一されたものでもないらしい。
.NETでは以下に140色とTransparent(透明)の141種類定義されている。
WindowsForms/ASP.NET : System.Drawing.Color構造体
WPF/Silverlight : System.Windows.Media.Colorsクラス


コード
XAML側はデフォルトでもOK.以下ではタイトルと画面サイズとを変更してます。
<Window x:Class="WpfColorNames.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfColorNames"
        Title="COLOR NAMES" Height="768" Width="1024">
    <Grid  />
</Window>

コードビハインド側
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;


namespace WpfColorNames
{
    public partial class MainWindow : Window
    {
        private Grid _grid;

        public MainWindow()
        {
            InitializeComponent();

            _grid = this.Content as Grid;

            for (int n = 0; n < 6; n++)
                _grid.ColumnDefinitions.Add(new ColumnDefinition());

            for (int n = 0; n < 30; n++)
                _grid.RowDefinitions.Add(new RowDefinition());

            Loaded += MainWindow_Loaded;

        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var label = this.CreateLabelDetail();

            _grid.Children.Add(label);

            this.CreateColorList().ForEach(entity =>
            {
                int row = entity.Row;

                _grid.Children.Add(CreateLabel(Colors.Transparent, entity.Category, row, entity.Col,label));

                entity.List.ForEach(color =>
                {
                    _grid.Children.Add(CreateLabel(color, GetColorName(color), ++row, entity.Col, label));
                });
            });
        }

        private List<Entity> CreateColorList()
        {
            var list = new List<Entity>();

            list.Add(new Entity
            {
                Category = "White",
                Col = 0,
                Row = 0,
                List = new List<Color> { Colors.White, Colors.Snow, Colors.Honeydew, Colors.MintCream, Colors.Azure, Colors.AliceBlue, Colors.GhostWhite, Colors.WhiteSmoke,
Colors.SeaShell,Colors.Beige,Colors.OldLace,Colors.FloralWhite,Colors.Ivory,Colors.AntiqueWhite,Colors.Linen,Colors.LavenderBlush,Colors.MistyRose}
            });

            list.Add(new Entity
            {
                Category = "Gray",
                Col = 0,
                Row = 18,
                List = new List<Color> {  Colors.Gainsboro, Colors.LightGray, Colors.Silver, Colors.DarkGray, Colors.Gray,Colors.DimGray, Colors.LightSlateGray, Colors.SlateGray,
Colors.DarkSlateGray, Colors.Black}
            });

            list.Add(new Entity
            {
                Category = "Red",
                Col = 1,
                Row = 0,
                List = new List<Color> {  Colors.LightSalmon, Colors.Salmon, Colors.DarkSalmon, Colors.LightCoral, Colors.IndianRed, Colors.Crimson, Colors.Red, Colors.Firebrick, Colors.DarkRed }
            });

            list.Add(new Entity
            {
                Category = "Brown",
                Col = 1,
                Row = 10,
                List = new List<Color> {  Colors.Cornsilk, Colors.BlanchedAlmond, Colors.Bisque, Colors.NavajoWhite, Colors.Wheat, Colors.BurlyWood, Colors.Tan, Colors.RosyBrown,
Colors.SandyBrown,Colors.Goldenrod,Colors.DarkGoldenrod,Colors.Peru,Colors.Chocolate,Colors.SaddleBrown,Colors.Sienna,Colors.Brown,Colors.Maroon }
            });

            list.Add(new Entity
            {
                Category = "Yellow",
                Col = 2,
                Row = 0,
                List = new List<Color> {  Colors.LightYellow, Colors.LemonChiffon, Colors.LightGoldenrodYellow, Colors.PapayaWhip, Colors.Moccasin, Colors.PeachPuff, Colors.PaleGoldenrod, Colors.Khaki, Colors.DarkKhaki, Colors.Gold,Colors.Yellow }
            });

            list.Add(new Entity
            {
                Category = "Pink",
                Col = 2,
                Row = 12,
                List = new List<Color> { Colors.Pink, Colors.LightPink, Colors.HotPink, Colors.DeepPink, Colors.PaleVioletRed, Colors.MediumVioletRed }
            });

            list.Add(new Entity
            {
                Category = "Orange",
                Col = 2,
                Row = 19,
                List = new List<Color> { Colors.Orange, Colors.DarkOrange, Colors.Coral, Colors.Tomato, Colors.OrangeRed }
            });

            list.Add(new Entity
            {
                Category = "Green",
                Col = 3,
                Row = 0,
                List = new List<Color> {  Colors.PaleGreen, Colors.LightGreen, Colors.YellowGreen, Colors.GreenYellow,Colors.Chartreuse, Colors.LawnGreen, Colors.Lime, Colors.LimeGreen,Colors.MediumSpringGreen,
Colors.SpringGreen,Colors.MediumAquamarine,Colors.Aquamarine,Colors.LightSeaGreen,Colors.MediumSeaGreen,Colors.SeaGreen,Colors.DarkSeaGreen,Colors.ForestGreen,
Colors.Green,Colors.DarkGreen,Colors.OliveDrab,Colors.Olive, Colors.DarkOliveGreen,Colors.Teal}
            });

            list.Add(new Entity
            {
                Category = "Blue",
                Col = 4,
                Row = 0,
                List = new List<Color> {  Colors.LightBlue, Colors.PowderBlue, Colors.PaleTurquoise, Colors.Turquoise, Colors.MediumTurquoise, Colors.DarkTurquoise, Colors.LightCyan, Colors.Cyan,Colors.Aqua,
Colors.DarkCyan,Colors.CadetBlue,Colors.LightSteelBlue,Colors.SteelBlue,Colors.LightSkyBlue,Colors.SkyBlue,Colors.DeepSkyBlue,Colors.DodgerBlue,Colors.CornflowerBlue,
Colors.RoyalBlue,Colors.Blue,Colors.MediumBlue,Colors.DarkBlue,Colors.Navy,Colors.MidnightBlue}
            });

            list.Add(new Entity
            {
                Category = "Purple",
                Col = 5,
                Row = 0,
                List = new List<Color> {  Colors.Lavender, Colors.Thistle, Colors.Plum, Colors.Violet, Colors.Orchid, Colors.Fuchsia, Colors.Magenta,Colors.MediumOrchid,
Colors.MediumPurple,/*Colors.Amethyst,*/Colors.BlueViolet,Colors.DarkViolet,Colors.DarkOrchid,Colors.Purple,Colors.DarkMagenta,Colors.SlateBlue,Colors.DarkSlateBlue,
Colors.MediumSlateBlue,Colors.Indigo}
            });

            return list;
        }



        private Label CreateLabel(Color color, string name, int row, int column, Label detal)
        {
            Label l = new Label();
            l.Content = name;
            l.Background = new SolidColorBrush(color);
            l.HorizontalContentAlignment = HorizontalAlignment.Center;
            l.VerticalContentAlignment = VerticalAlignment.Center;
            l.Padding = new Thickness(0);
            l.Margin = new Thickness(3, 1, 3, 0);
            if (color != Colors.Transparent)
            {
                l.MouseEnter += (_, __) =>
                {
                    Brush b = ((Label)_).Background;
                    detal.Background = b;

                    detal.Content = string.Format("{0}({1}){2}A:{3} R:{4} G:{5} B:{6}",
                        name, b, Environment.NewLine,
                        Convert.ToInt32(b.ToString().Substring(1, 2), 16),
                        Convert.ToInt32(b.ToString().Substring(3, 2), 16),
                        Convert.ToInt32(b.ToString().Substring(5, 2), 16),
                        Convert.ToInt32(b.ToString().Substring(7, 2), 16));
                };
            }
           
            Grid.SetRow(l, row);
            Grid.SetColumn(l, column);

            return l;
        }

        private Label CreateLabelDetail()
        {
            Label l = new Label();
            l.HorizontalContentAlignment = HorizontalAlignment.Center;
            l.VerticalContentAlignment = VerticalAlignment.Center;
            l.Padding = new Thickness(0);
            l.Margin = new Thickness(3);
            l.BorderBrush = new SolidColorBrush(Colors.White);
            l.BorderThickness = new Thickness(2);
            l.FontSize = 22;
            Grid.SetRow(l, 25);
            Grid.SetRowSpan(l, 5);
            Grid.SetColumn(l, 2);
            Grid.SetColumnSpan(l, 4);

            return l;
        }

        private string GetColorName(Color color)
        {
            var temp = typeof(Colors).GetProperties().FirstOrDefault(p => Color.AreClose((Color)p.GetValue(null), color)).Name;
            return temp == "Fuchsia" ? "Fuchsia/Magenta" : temp == "Aqua" ? "Aqua/Cyan" : temp;
        }

    }

    class Entity
    {
        public string Category { get; set; }
        public Color Foreground { get; set; }
        public int Col { get; set; }
        public int Row { get; set; }
        public List<Color> List { get; set; }
    }
}

解説
色の名前はどう並べても上手く並びません。RGB値にカラーチャートのような規則性もなければ、命名も適当な感じです。RGB値が同じのも2ペアあったりします。
サンプルでは適当にカテゴライズして適当に並べてます。

未設定(Null)とTransparent(透明)との違い
Nullの場合はHitTestに当たらないのでクリックイベントなどが拾えなくなる。Transparentは透明という色なのでちゃんと拾える。
Converterなどを作る場合にちょっと考慮が必要だったりする。
posted by RR at 22:42 | Comment(0) | サンプルプログラム  | このブログの読者になる | 更新情報をチェックする

2016年02月25日

WPF 色の名前と色の表示 その2

完成画面イメージ
ColorNames2.png

概要

前回と同じですが、実装をちょっと変えています。
色には名前の付いたものが140あります。
トマト色とか鮭(サーモン)色ぐらいならなんとかイメージありますが、ペルー色とか蘭色なんて言われてもピンと来るものがない。
インテリセンスで出てくる単語から色をイメージするのはかなりハードルが高いです。
ネット上のサンプルカラーも.NETのもと一致するのか良くわからないので(統一規格でもないらしい)
カラーサンプル表示プログラムを実装してみました。

画面側(XAML側)
ItemsControlというコントロールを使います。グリッドやリストなど複数の要素を持つ親クラスみたいたものです。
コンテナとしてWrapPanelを使用。画面サイズを変えると並びが変ります。各色はLabelの背景色で表示させます。
これらは、DataContextを介してバインドされたコレクションが表示されます。

<Window x:Class="WpfColorNames2.MainWindow"
        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:WpfColorNames2"
        Title="WPF Color Names 2" Height="350" Width="525">
    
        <ItemsControl ItemsSource="{Binding}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.Resources>
                <Style TargetType="Label">
                    <Setter Property="Height" Value="40" />
                    <Setter Property="Width"  Value="120" />
                    <Setter Property="Margin" Value="5" />
                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                </Style>
            </ItemsControl.Resources>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Label Content="{Binding Contents}" Foreground="{Binding Foreground}" Background="{Binding Background}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    
</Window>


コードビハインド側
色の一覧はColorsクラスのメンバをリフレクションで取得します。
取得したColorからバインド用のクラスを生成する。
一覧からTransparent(透明)を覗いて薄い(明るい)色順に並べて
DataContextに設定する。
色の選定も適当みたいで何順に並べても全然綺麗なチャートにはなりません。残念。

using System;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Media;

namespace WpfColorNames2
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.Loaded += (_, __) =>
            {
                // 色の一覧をリフレクションで取得しバインド用にEntityクラスに変換する
                var list = typeof(Colors).GetProperties().Select<PropertyInfo, Entity>(p =>
                {
                    Color c = (Color)p.GetValue(null);

                    return new Entity
                    {
                        Color = c,
                        Name = p.Name,
                        Alpha = Convert.ToByte(c.ToString().Substring(1, 2), 16),
                        Red = Convert.ToByte(c.ToString().Substring(3, 2), 16),
                        Green = Convert.ToByte(c.ToString().Substring(5, 2), 16),
                        Blue = Convert.ToByte(c.ToString().Substring(7, 2), 16)
                    };
                });
                // Transparentを除外し色の薄い順に並べる
                // OrderBy(OrderbyDescending)を各種試行してみたが、いい並び順が見つからない
                // 下記は明るい順にしている。名前順よりはマシだと思う
                this.DataContext = list.Where(ent => ent.Color != Colors.Transparent).OrderByDescending(ent => ent.Red + ent.Green + ent.Blue).ToList();
            };
        }
    }

    public class Entity
    {
        public Color Color { get; set; }
        public SolidColorBrush Foreground { get { return new SolidColorBrush((Red + Green + Blue) > 255 ? Colors.Black : Colors.White); } }
        public SolidColorBrush Background { get { return new SolidColorBrush(Color); } }
        public string Name { get; set; }
        public string Contents { get { return Name + Environment.NewLine + Color; } }
        public byte Alpha { get; set; }
        public byte Red { get; set; }
        public byte Green { get; set; }
        public byte Blue { get; set; }
    }
}
posted by RR at 22:45 | Comment(0) | サンプルプログラム  | このブログの読者になる | 更新情報をチェックする