i++

プログラム系のメモ書きなど

C#/.NET : インストールされているドライバーのリストを調べる、検索する

サンプルコード

※「参照の追加」で「System.Management」を追加する必要があります(アセンブリフレームワーク)。

System.Management.SelectQuery query = new System.Management.SelectQuery("Win32_SystemDriver");
// 特定のドライバーを検索したい場合は query.Condition で条件を指定。
// query.Condition = "Name = 'driver_name'";
System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(query);
var drivers = searcher.Get();
foreach(var d in drivers)
{
    Console.WriteLine("=== Properties ===");
    foreach(var p in d.Properties)
    {
        // d.p["プロパティ名"] は d["プロパティ名"] と同じ 
        Console.WriteLine(p.Name + ":" + p.Value);
    }
    }
    Console.WriteLine("=== System Propertides ===");
    foreach (var p in d.SystemProperties)
    {
        Console.WriteLine(p.Name + ":" + p.Value);
    }
    Console.WriteLine("=== Qualifiers ===");
    foreach (var q in d.Qualifiers)
    {
        Console.WriteLine(q.Name + ":" + q.Value);
    }
}

参考

WPF/XAML : DataGrid の表示内容を TextBox への入力内容でフィルタリングする

ポイントは以下の3点です。

  • DataGrid の ItemsSource に CollectionViewSource.View を使う
  • CollectionViewSource.Filter にフィルタリング用の関数を登録する
  • TextBox の入力に変更がある度に CollectionViewSource.View.Refresh() を呼ぶ

サンプルコード

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

private ObservableCollection<Person> mPersonObservableCollection;
private CollectionViewSource mPersonCollectionViewSource;

public MainWindow()
{
    InitializeComponent();

    // この辺りで DataGrid のソースとフィルター関数を登録
    mPersonObservableCollection = new ObservableCollection<Person>();
    mPersonCollectionViewSource = new CollectionViewSource();
    mPersonCollectionViewSource.Filter += Person_Filter;
    mPersonCollectionViewSource.Source = mPersonObservableCollection;
    PersonDataGrid.ItemsSource = mPersonCollectionViewSource.View
}

private void Person_Filter(object sender, FilterEventArgs e)
{
    if (e.Item != null)
    {
        // テキストが空の時はフィルタリングなし
        if (String.IsNullOrEmpty(PersonFilterTextBox.Text))
        {
            e.Accepted = true;
        }
        else
        {
            // 部分一致を受け入れる
            Person p = e.Item as Person;
            e.Accepted = p.Name.Contains(PersonFilterTextBox.Text);
        }
    }
}

Android : ListView (ArrayAdapter) で使う View に RadioGroup.setOnCheckedChangeListener を使うと起こる問題について

原因や問題が起きる条件が全く解明できていないものの、ひとまずメモ。

  • ListView で表示する項目の View に RadioGroup を含める
  • その RadioGroup に setOnCheckedChangeListener を設定し、その中でデータ(getItem(position) で得られるもの)を変更する

としていたところ、ListView をスクロールすると変更内容が失われて、RadioGroup の設定状態が元に戻ってしまっていました(というよりも、変なタイミングで RadioGroup.setOnCheckedChangeListener に設定したリスナーが呼ばれて変更内容が巻き戻ってしまっていた感じかもしれません)。ちなみに RadioButton の setOnCheckedChangeListener でも同じ症状が見られました。

ひとまず解決策として、各 RadioButton の setOnClickListner でデータの変更を行うことに。これなら、クリック時のみにデータの変更が行われるのでスクロール時に勝手に呼ばれてデータが書き換わることはありません。

また、RadioButton の OnClickListener はチェック状態が変わった後(RadioButton の OnCheckedChangeListener に設定したリスナーが呼ばれた後)に呼ばれるので、CompoundButton にキャストして isChecked ですれば変更後(=現在)の状態が取得できます。

Android : Toolbar + DrawerLayout で Drawer を一時的に無効にして Navigation Icon (homeAsUpIndicator) を変更する

  • ActionBarDrawerToggle.setDrawerIndicatorEnabled(false) で「ハンバーガーアイコン + Drawer の開閉」を無効にすると、 setToolbarNavigationClickListener で設定したリスナーが呼ばれるようになる
  • Toolbar.setNavigationIcon で Navigation Icon (左上のアイコン)が変更できる
  • 注意ActionBarDrawerToggle.setDrawerIndicatorEnabled(false) の後に Toolbar.setNavigationIcon を呼ぶ必要がある(そうしないとアイコンが表示されませんでした)
    • Toolbar の homeAsUpIndicator を Theme や Style で設定しておくことはできないらしいので、コード上で行う必要があります
  • ジェスチャー(画面端からのスワイプ)によって Drawer が開かれないようにするには DrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSE) を呼ぶ
    • ジェスチャーを再び有効にするには DrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)

ActionBarDrawerToggle.setToolbarNavigationClickListener のリファレンスの文章あたりが参考になります。

When DrawerToggle is constructed with a Toolbar, it sets the click listener on the Navigation icon. If you want to listen for clicks on the Navigation icon when DrawerToggle is disabled (setDrawerIndicatorEnabled(boolean), you should call this method with your listener and DrawerToggle will forward click events to that listener when drawer indicator is disabled.

最近 kotlin を使ってみているのでサンプルは kotlin で(kotlin ははてなシンタックスハイライトできないんですね…。とりあえず言語的に近いと言われている swift でハイライトしてみています)。

一部の変数はメンバー変数に置いているので var や val は抜けています。
Java を使ってどうすればよいかも、だいたいは察しがつくはず…。

初期化部分

AndroidStudio で新規プロジェクトを作成した際に自動生成されるものと基本的に変わりないです。

toolbar = findViewById(R.id.toolbar) as Toolbar
setSupportActionBar(toolbar)

drawer = findViewById(R.id.drawer_layout) as DrawerLayout
toggle = ActionBarDrawerToggle(
        this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawer?.setDrawerListener(toggle)
toggle?.syncState()

// ハンバーガーアイコン + Drawer 無効時に Navigation Icon をクリックした際の挙動
// ここでは Drawer を再び有効にしています
toggle?.setToolbarNavigationClickListener {
    toggle?.isDrawerIndicatorEnabled = true
    drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
}

ハンバーガーアイコンによる Drawer の開閉を無効にする部分

// 順序注意! Enabled を false にした後に Icon を設定する必要があります
toggle?.isDrawerIndicatorEnabled = false
toolbar?.setNavigationIcon(R.drawable.ic_check)
drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)

参考

プログラマの英語 : Power off と Shutdown

Linux 等のコマンドの違いの話ではなく、Power Off(電源を切る) と Shutdown(シャットダウン)、それぞれの語から受ける言葉の印象の話です。

どちらも同じ結果を意図して違いを意識せずに用いられる事が多いと思いますが、それぞれ以下のようなニュアンスなのではないかと。

  • Power Off
    • メインの目的は(電気的に)電力を落とす
    • コンピュータや何らかのシステムに対して行う場合、安全に電力を落とすためにその前処理として終了処理をして停止状態に移行する(こともある)
  • Shutdown
    • メインの目的はコンピュータやシステムを停止状態にする
      • そのための一連の処理を行うこと
    • 停止状態にした結果として、場合によっては電力を落とす
    • Boot の対義語というイメージ

WPF/XAML : TextBox に入力ヒントを表示する

WPF界隈では hint ではなく watermark とも呼ぶらしいですね。Android の方では watermark という呼び方を聞いたことはないのですが。

参考にしたサイト(下記記載)には AttachedProperty を使った方法や Trigger を使った方法も掲載されており、「TextBox に」という点ではそれらを実装するのが筋のような気もしますが、ここでは Extended WPF Toolkit Community EditionWatermarkTextBox の使い方をまとめます。

参照を追加して使うだけなのでとても簡単です。使えるものは積極的に使っていきましょう。

f:id:tkyjhr:20150830085159p:plain

手順

  1. Nuget で Extended.Wpf.Toolkit をインストール
  2. xaml の namespace に "xmlns:extk="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit" を追加する
    • ※ extk の部分は好みの文字列でどうぞ
  3. TextBox の代わりに extk:WatermarkTextBox を使い、Watermark プロパティを設定する
WatermarkTextBox を使うだけのサンプルの xml
<Window x:Class="WpfApplication1.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:extk="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <extk:WatermarkTextBox Watermark="First Name" Margin="8,8,8,0"/>
        <extk:WatermarkTextBox Watermark="Family Name" Margin="8,8,8,0"/>
    </StackPanel>
</Window>

参考

プログラマの英語 : state と status の違い・使い分け

どちらも「状態」を意味し、普通の英文として使う場合でも、コード中の変数名や enum 定義に使用する場合でも、往々にして交換可能なのですが、全く同じ意味合いを持っているという訳ではありません。

そのニュアンスの違いと使い分け方について考えてみます。

state とは

Oxford Dictionaries による定義:

The particular condition that someone or something is in at a specific time

私の解釈:

  • status の特定の状態(スナップショット)で名前を持っている
  • 同種のカテゴリに属する state は同時に取り得ない

定義中の particular(特定の)という言葉が重要な気がしています。
「…という状態」と簡単に言い表せる、と解釈できるかもしれません。

代入式の右辺としての使用を主目的に定義されるイメージが強いです(もちろん右辺に使われるということは左辺に入るのですが…)。

CurrentState = StateBusy;

status とは

Oxford Dictionaries による定義:

The situation at a particular time during a process

私の解釈:

  • ある種の状態の集合、カテゴリ
    • 同種のものをまとめた場合もあれば、異種のものをまとめる場合もある
      • 同種の例:HTTPステータス
      • 異種の例:ステータスバー(アプリケーションの多様な情報をまとめて「状態」として表示)
  • 演算(増減)可能なパラメータの場合もある
    • 例:ゲームのキャラクターの HP や攻撃力といった「ステータス」(一方「毒状態」などの状態は State なイメージ。毒や麻痺などをまとめた「状態異常」になると Status。)

「…の状態(status of ...)」の印象が大きいです。 もっとも「…の状態」は state of を使う場合も多いのでこれだけでは何も言っていないに等しいのですが…。

代入式の左辺としての使用を主目的に定義されるイメージが強いです(同上…)。

xxxStatus = FlagA | FlagB | FlagC | ... ;

コード内での使い分け方

  • status も state もなるべく変数名や定数定義に使わず、その「状態」を表す具体的な語を探す
    • errorStatus ではなく errorCode など
  • 一般用語に倣う(HTTPステータスなど)
  • 既にあるコードや参考にしているライブラリに倣う
    • 一貫性 > 用語としての正確性

という方針を優先しつつ、どうしても新しく status か state を導入する必要が出た場合には

  • 排他的な状態の場合 state を使う
  • 状態の集合(フラグのセットなど)の場合 status を使う

という感じでしょうか。
後で一貫性を保ちやすいよう、自分が納得できる使い方をするのが一番かと思います。

参考