< June 2009 | July 2009 | August 2009 >

July 14, 2009

リンクローカルな IPv6 アドレスにつけるインターフェース番号を確認する

C:\>netsh interface ipv6 show interface
アクティブ状態を照会しています...

Idx  Met   MTU    State         Name
---  ----  -----  ------------  -----
  6     2   1280  Disconnected  Teredo Tunneling Pseudo-Interface
  5     0   1500  Connected     ローカル エリア接続
  4     0   1500  Connected     ローカル エリア接続 2
  3     1   1280  Connected     6to4 Pseudo-Interface
  2     1   1280  Connected     Automatic Tunneling Pseudo-Interface
  1     0   1500  Connected     Loopback Pseudo-Interface

July 10, 2009

インストールされている .NET Framework のバージョンをチェックするスクリプト

.NET Frameworkのバージョンを確認する方法を参考に WSH スクリプトを書いた。

拡張子を .wsf で保存して実行してくださいねー。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="Registry">
<?job error="True" debug="True" ?>
<script language="JScript">
<![CDATA[
    var checker = new DotNetChecker ();
    var result = "";
    result += checker.FormatResult (checker.Check10 (), ".NET Framework 1.0");
    result += checker.FormatResult (checker.Check11 (), ".NET Framework 1.1");
    result += checker.FormatResult (checker.Check11JP (), "    Japanese Langage Pack");
    result += checker.FormatResult (checker.Check20 (), ".NET Framework 2.0");
    result += checker.FormatResult (checker.Check20JP (), "    Japanese Langage Pack");
    result += checker.FormatResult (checker.Check30 (), ".NET Framework 3.0");
    result += checker.FormatResult (checker.Check30JP (), "    Japanese Langage Pack");
    result += checker.FormatResult (checker.Check35 (), ".NET Framework 3.5");
    result += checker.FormatResult (checker.Check35JP (), "    Japanese Langage Pack");

    WScript.Echo (result);

    function DotNetChecker ()
    {
        this.reader = new RegReader ();

        this.Check10 = function ()
        {
            var install = this.reader.RegRead ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\Full\\v1.0.3705\\1041\\Microsoft .NET Framework Full v1.0.3705 (1041)\\Install");
            if (install == null || "" + install == "0")
                return null;

            var version = this.reader.RegRead ("HKLM\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{78705f0d-e8db-4b2d-8193-982bdda15ecd}\\Version");
            if (version == null)
                version = this.reader.RegRead ("HKLM\\SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{FDC11A6F-17D1-48f9-9EA3-9051954BAA24}\\Version");
            if (version == null)
                return 0;

            var regex = /^1,0,3705,(\d+)$/;
            var m = regex.exec (version);
            var sp = 0;
            if (m != null && m.length > 1)
                sp = m [1] - 0;

            return sp;
        }

        this.Check11 = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322");
        }

        this.Check20 = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727");
        }

        this.Check30 = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0");
        }

        this.Check35 = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5");
        }

        this.Check11JP = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322\\1041");
        }

        this.Check20JP = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727\\1041");
        }

        this.Check30JP = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0\\1041");
        }

        this.Check35JP = function ()
        {
            return this.CheckKey ("HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5\\1041");
        }

        this.CheckKey = function (key)
        {
            var install = this.reader.RegRead (key + "\\Install");

            if (install == null || "" + install == "0")
                return null;

            var sp = this.reader.RegRead (key + "\\SP");
            if (sp == null)
                sp = 0;
            return sp;
        }

        this.FormatResult = function (value, label)
        {
            var result = label;

            switch (value)
            {
            case null:
                result += ": not installed.\n"; break;
            case 0:
                result += ": installed.\n"; break;
            default:
                result += ": SP" + value + " installed.\n"; break;
            }
            return result;
        }

    }

    function RegReader ()
    {
        this.shell = WScript.CreateObject ('WScript.Shell');

        this.RegRead = function (name)
        {
            var ret = null;
            try
            {
                ret = this.shell.RegRead (name);
            }
            catch (e)
            {
                //WScript.Echo (e.number + "\n" + e.description);
            }
            return ret;
        }

        return this;
}
]]>
</script>
</job>
</package>

July 2, 2009

TextBox に長さ制限を設ける

WPF の TextBox の MaxLength が TSF 環境下で使い物にならない件ですが、Feedback への Microsoft からの回答によると、次期バージョンで何とかなる、のかな?

とはいえ、今抱えてる案件は .NET Framework 3.5 で対応しなきゃいけないわけで。添付プロパティを使って無理矢理対応してみました。時間があったらまた詳しく書きます。
※ バイト数単位で切ることはできません。文字数単位です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace MaxLength
{
    public class LengthCheck
    {
        /// <summary>
        /// 指定された System.Windows.Controls.TextBox から LengthCheck.MaxLength 添付プロパティの値を取得します。
        /// </summary>
        /// <param name="textBox">プロパティ値の読み取り元の要素。</param>
        /// <returns>LengthCheck.MaxLength 添付プロパティの値。</returns>

        public static int GetMaxLength (TextBox textBox)
        {
            return (int) textBox.GetValue (MaxLengthProperty);
        }


        /// <summary>
        /// LengthCheck.MaxLength 添付プロパティの値を、指定された System.Windows.Controls.TextBox に設定します。
        /// </summary>
        /// <param name="textBox">添付プロパティを設定する要素。</param>
        /// <param name="value">設定するプロパティ値。</param>

        public static void SetMaxLength (TextBox textBox, int value)
        {
            textBox.SetValue (MaxLengthProperty, value);
        }


        /// <summary>
        /// LengthCheck.MaxLength 添付プロパティを識別します。
        /// </summary>

        public static readonly DependencyProperty MaxLengthProperty =
            DependencyProperty.RegisterAttached ("MaxLength", typeof (int), typeof (LengthCheck), new FrameworkPropertyMetadata (0, new PropertyChangedCallback (MaxLengthProperty_Changed)));


        /// <summary>
        /// LengthCheck.MaxLength 添付プロパティの値が変更された際に、コントロール側にイベントハンドラを設定します。
        /// </summary>
        /// <param name="d">添付プロパティが設定された要素。</param>
        /// <param name="e">イベントの引数。</param>

        static void MaxLengthProperty_Changed (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var textBox = d as TextBox;

            if (textBox != null)
            {
                try
                {
                    int newValue = (int) e.NewValue;

                    // MaxLength プロパティを設定する。
                    textBox.MaxLength = newValue;
                    if (newValue == 0)
                    {
                        // イベントハンドラ解除
                        TextCompositionManager.RemoveTextInputStartHandler (d, new TextCompositionEventHandler (OnTextInputStart));
                        TextCompositionManager.RemovePreviewTextInputHandler (d, new TextCompositionEventHandler (OnPreviewTextInput));
                    }
                    else
                    {
                        // イベントハンドラ設定
                        TextCompositionManager.AddTextInputStartHandler (d, new TextCompositionEventHandler (OnTextInputStart));
                        TextCompositionManager.AddPreviewTextInputHandler (d, new TextCompositionEventHandler (OnPreviewTextInput));
                    }
                }
                catch
                {// 無視する
                }
            }
        }


        /// <summary>
        /// 新しい TextComposition が開始されると発生します。
        /// </summary>
        /// <param name="sender">イベント ハンドラがアタッチされているオブジェクト。</param>
        /// <param name="e">イベントのデータ。</param>

        static void OnTextInputStart (object sender, TextCompositionEventArgs e)
        {
            // IME が ON の場合は MaxLength を無効にする。

            var ime = InputMethod.Current;
            var textBox = e.Source as TextBox;
            if (textBox != null && ime.ImeState == InputMethodState.On)
                textBox.MaxLength = 0;

        }


        /// <summary>
        /// TextComposition が完了したときに発生します。
        /// </summary>
        /// <param name="sender">イベント ハンドラがアタッチされているオブジェクト。</param>
        /// <param name="e">イベントのデータ。</param>

        static void OnPreviewTextInput (object sender, TextCompositionEventArgs e)
        {
            // 入力確定時に MaxLength を再設定する。

            var ime = InputMethod.Current;
            var textBox = e.Source as TextBox;
            if (textBox != null && ime.ImeState == InputMethodState.On)
            {
                textBox.MaxLength = GetMaxLength (textBox);
                textBox.Text = textBox.Text.Substring (0, GetMaxLength (textBox));
            }
        }
    }
}
続きを読む...

July 1, 2009

RadioButton を ListBox で実装する 4

RadioButton を ListBox で実装する 3 のカスタムコントロールを使ってみる。

まず、コードビハインドで適当なコレクションを突っ込んでみる (例は配列だけど)

using System.Net.NetworkInformation;
using System.Windows;

namespace WpfSample
{
    /// <summary>
    /// Window1.xaml の相互作用ロジック
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1 ()
        {
            this.DataContext = NetworkInterface.GetAllNetworkInterfaces ();
               
            InitializeComponent ();
        }
    }
}

作成したカスタムコントロールをウインドウに配置して、ItemsSource プロパティを設定する。本当は ItemsSource は DataContext じゃなく別の方法で提供すべきだと思うけど、今回は単に表示するのが目的なので。

RadioButton のキャプションとして表示したいメンバのパスを DisplayMemberPath に設定しとく。

<Window x:Class="WpfSample.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfSample"
        Title="RadioButton を ListBox で実装する" SizeToContent="WidthAndHeight">

    <Grid>
        <local:RadioButtonsControl ItemsSource="{Binding}" DisplayMemberPath="Name" />
    </Grid>
</Window>

実行すると、こんな感じ。ちゃんと NIC の Name が表示されている。

radiolist_custom.png

RadioButton を ListBox で実装する 3

RadioButton を ListBox で実装するRadioButton を ListBox で実装する 2の続き。

カスタムコントロールにしてみた。

RadioButtonsControl.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfSample
{
    /// <summary>
    /// 選択可能な項目をラジオボタンで選択するコントロール
    /// </summary>

    public class RadioButtonsControl : ListBox
    {
        /// <summary>
        /// クラスの初期化
        /// </summary>

        static RadioButtonsControl ()
        {
            // プロパティのデフォルト値を上書きする
            DefaultStyleKeyProperty.OverrideMetadata (typeof (RadioButtonsControl), new FrameworkPropertyMetadata (typeof (RadioButtonsControl)));
            BackgroundProperty.OverrideMetadata (typeof (RadioButtonsControl), new FrameworkPropertyMetadata (Brushes.Transparent));
            BorderBrushProperty.OverrideMetadata (typeof (RadioButtonsControl), new FrameworkPropertyMetadata (Brushes.Transparent));
        }


        /// <summary>
        /// コントロール内にラジオボタンを並べる列数を取得または設定します。これは、依存関係プロパティです。
        /// </summary>
        /// <value>コントロール内の列の数。既定値は 0 です。</value>

        public int Columns
        {
            get { return (int) GetValue (ColumnsProperty); }
            set { SetValue (ColumnsProperty, value); }
        }


        /// <summary>
        /// RadioButtonControl.Columns 依存関係プロパティを識別します。
        /// </summary>

        public static readonly DependencyProperty ColumnsProperty =
            DependencyProperty.Register ("Columns", typeof (int), typeof (RadioButtonsControl), new FrameworkPropertyMetadata (0));


        /// <summary>
        /// コントロール内にラジオボタンを並べる行数を取得または設定します。これは、依存関係プロパティです。
        /// </summary>
        /// <value>コントロール内の行の数。既定値は 0 です。</value>

        public int Rows
        {
            get { return (int) GetValue (RowsProperty); }
            set { SetValue (RowsProperty, value); }
        }


        /// <summary>
        /// RadioButtonControl.Rows 依存関係プロパティを識別します。
        /// </summary>

        public static readonly DependencyProperty RowsProperty =
            DependencyProperty.Register ("Rows", typeof (int), typeof (RadioButtonsControl), new FrameworkPropertyMetadata (0));
    }
}


Generic.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfSample">

    <Style TargetType="{x:Type local:RadioButtonsControl}">
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
        <Setter Property="ScrollViewer.CanContentScroll" Value="true" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="SelectionMode" Value="Single" />
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <UniformGrid
                            Columns="{Binding Path=Columns, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:RadioButtonsControl}}}"
                            Rows="{Binding Path=Rows, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:RadioButtonsControl}}}" />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Margin" Value="5" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <RadioButton
                                        IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}}">
                                    <ContentPresenter />
                                </RadioButton>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:RadioButtonsControl}">
                    <Border SnapsToDevicePixels="True" x:Name="Bd" Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}" Padding="1">
                        <ScrollViewer Focusable="False" Padding="{TemplateBinding Padding}">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>