C# WPFプログラミングの迷い道

C# WPFで株式投資ツールの作成に挑戦する!

株式コードを探すプログラムを考える

C# WPFを使って、ListViewに表示された株価コードと銘柄名のリストをTextBoxに入力したテキストを使って絞り込むプログラムを作成します。

 

PanRollingチャートギャラリー(体験版を使用しています)で、提供されているCOMモデルでは、株式コードが存在するかどうかを確認するメソッドが提供されていません。データベースに存在しない株式コードを入力するとエラーが発生します。

※ COMモデル関連の情報は、検索エンジンでは、キーワードが、ドメインのcomと競合するため、情報は、かなり探しにくいです。

エラー処理は、コストが高い、つまり、処理が遅くなるため、可能な限り回避するのが基本方針です。理想的には、エラー処理コードと回避処理コードの処理速度を比較検討する必要があるのかもしれません。

株式コードの検索と株式コードが存在するかどうかを確認できるプログラムを作成します。

株式コードの一覧をPanRollingチャートギャラリーで取得する方法は、すでに紹介しています。

 

kukekko.hateblo.jp

 

実現したい機能は、以下の2つです。

  • 取得した株式コードの一覧から、入力したコードが存在するかどうかを確認する
  • 完全な株式名称だけでなく、よみがな、略式名称でもコードを検索できるようにする(今回は実装しない)

以前に、PanRollingチャートギャラリー(体験版を使用しています)から、株式コードと銘柄名を取得するプログラムを作成しました。

 

このとき作成したプログラムで得られた株式コードと銘柄名のリストから、TextBoxに入力した文字で、リストを絞り込むプログラムを作成しようと思います。

ListViewから、項目を絞り込む機能を実装する

実際に使用するモジュールとして機能を追求していくと理解しにくくなります。

コードをどのように実装するかを考えるために、機能を単純に、以下のように変更します。

1つの項目に、2つのデータを持つ、List型のデータの中から、実行時に、TxetBoxに入力した文字が含まれる項目だけ、表示するプログラムを考えます。

C# WPFで、ListViewのリストをTextBoxに入力したテキストで絞り込むプログラム

プログラム全体を考える前に、C# WPFを使って、ListViewに表示されてたリストをTextBoxに入力したテキストを使って絞り込むプログラムを確認します。

 

vdlz.xyz

ポイント

  • データクラスに、IEquatable<T> インターフェイスを実装し、Equalsメソッドを使えるようにする
  • TextBoxに入力した文字で、GridViewに表示するリストから、LINQを使って、フィルタリングしたリストを作成する
  • 作成したフィルタリングしたリストをつなげて、重複を削除する。
  • 最終的なリストをGridViewのItemsSourceに指定する。

Pan Active Market DatabaseをC#で使用するための参照設定

PanRollingチャートギャラリーの体験版は、「 Pan Rolling相場アプリケーション試用版」としてダウンロードできます。

        
  1. WPFアプリケーションを作成する
  2.     
  3. 参照を追加する
  4.     
  5. [プロジェクト] - [参照の追加] - [COM] タブ を選択
  6.     
  7. Pan Active Market Database 1.3にチェック
  8.     
  9. ActiveMarket という参照が追加される。
  10.     

    

使用されている COM DLL は、amarket.dll です。

    

    

Pan Active Market Database 1.3にチェック

    
Pan Active Market Database 1.3にチェック
    

完成したアプリケーションの実行結果

ListViewに表示された株価コードと銘柄名のリストをTextBoxに入力したテキストを使って絞り込むプログラム

ListViewに表示された株価コードと銘柄名のリストをTextBoxに入力したテキストを使って絞り込むプログラム

ListViewのリストをTextBoxに入力したテキストで絞り込む機能を実装する

以前作成した、銘柄と株式コードを取得するC# WPFアプリケーションに、銘柄や株式コードを絞り込む機能を実装します。

IEquatable<T> インターフェイスを実装したデータクラスを作成する

最初に行うのは、株式コードと銘柄名を格納するデータクラスを作成することです。

このプログラムには、TextBoxに入力した文字で、リストをフィルタリングする機能を実装します。TextBoxに入力された文字を使って、株式コードと銘柄名のそれぞれをフィルタリングしたリストを作成し、その2つのリストから、1つの重複のないリストを作成します。

そのため、データクラスには、同じかどうかを確認するためのメソッドが必要です。

データクラス、stock_CodeAndNameは、銘柄名と株式コードに対応するstock_nameとstock_codeの2つのstring型のデータメンバを持っています。

データメンバを複数持つクラスでは、同じかどうかを確認するためのメソッドは、自動で実装してくれないので、自分で実装する必要があります。

クラスのインスタンスが、同じかどうか確認するには、IEquatable インターフェイスを継承し、 EqualsメソッドとGetHashCodeメソッドを実装する必要があります。

データクラス

stock_CodeAndName.cs

using System;
    using System.Collections.ObjectModel;
    
    namespace PanChart_GetStockCode
    {
        class stock_CodeAndName : IEquatable<stock_CodeAndName>
        {
            public string stock_name { get; set; }  // 銘柄名
            public string stock_code { get; set; }  // 株式コード
    
            public stock_CodeAndName(string code, string name)
            {
                stock_code = code;
                stock_name = name;
            }
            public stock_CodeAndName(object code, object name)
            {
                stock_code = Convert.ToString(code);
                stock_name = Convert.ToString(name);
            }
            // 同じかどうか比較する
            public bool Equals(stock_CodeAndName other)
            {
                if (other == null)
                    return false;
    
                if (this.stock_code == other.stock_code)
                    return true;
                else
                    return false;
            }
            public override bool Equals(Object obj)
            {
                if (obj == null)
                    return false;
    
                stock_CodeAndName productObj = obj as stock_CodeAndName;
                if (productObj == null)
                    return false;
                else
                    return Equals(productObj);
            }
            public override int GetHashCode()
            {
                // productCodeをint型に変換し、ハッシュコードにします。
                if (Int32.TryParse(this.stock_code, out int j))
                    return j;
                else
                    // 文字列からハッシュコードを生成します。
                    return this.stock_code.GetHashCode();
            }
        }
    }

ウィンドウのデザインを作成する

ウィンドウのデザインをxamlコードで作成します。

MainWindw.xaml

<Window x:Class="PanChart_GetStockCode.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                Title="株式銘柄リスト" Height="400" Width="350">
            <DockPanel>
        
                <Grid  DockPanel.Dock="top">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="2*"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <TextBlock Name="stock_code_box" 
                               Height="23" Grid.Column="0"/>
                    <TextBlock Name="stock_name_box" 
                               Height="23" Grid.Column="1"/>
                </Grid>
                <TextBox Name="ItemSerch" DockPanel.Dock="Top" TextChanged="ItemSerch_TextChanged" />
                <ListView Name="TradingNameList" DockPanel.Dock="Bottom" SelectionChanged="TradingNameList_SelectionChanged">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Header="株式コード" 
                                            DisplayMemberBinding="{Binding stock_code}" />
                            <GridViewColumn Header="銘柄名" 
                                            DisplayMemberBinding="{Binding stock_name}" />
                        </GridView>
                    </ListView.View>
                </ListView>
            </DockPanel>
        </Window>

部分コードを作成します

SetStockDataメソッドで、ListViewのItemsSourceに設定するリストを作成します。リストは、ウィンドウのコンポーネントにデータ結合させたいので、List<T>型ではなく、ObservableCollection<T>型を使用します。

ListViewには、SelectionChangedイベントを設定し、項目を選択すると、TextBlockに表示するコードを記述します。

そして、TextBoxにTextChangedイベントを設定し、文字が入力されると、入力した文字で、ListViewに表示されるリストが、フィルタリングされるように、コードを記述します。

MainWindw.xaml.cs

using System.Collections.ObjectModel;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace PanChart_GetStockCode
    {
        /// <summary>
        /// MainWindow.xaml の相互作用ロジック
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                // ListViewに、ソースを設定する
                SetStockData();
            }
    
            ObservableCollection<stock_CodeAndName> CodeAndNames = new ObservableCollection<stock_CodeAndName>();
    
            public void SetStockData()
            {
                ActiveMarket.Names Names = new ActiveMarket.Names();
    
                System.Array codeArray;
                System.Array nameArray;
    
                Names.AllNames(ActiveMarket._KindFlag.AM_KINDFLAG_SPOTS, out codeArray, out nameArray);
    
                for (int i = 0; i < codeArray.Length; i++)
                {
                    CodeAndNames.Add(new stock_CodeAndName(codeArray.GetValue(i + 1), nameArray.GetValue(i + 1)));
                }
    
                TradingNameList.ItemsSource = CodeAndNames;
            }
    
            private void TradingNameList_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
    
                // 項目を選択したとき、それぞれのメンバを表示する
    
                // ListViewで何も選択されていない場合は何もしない
                if (TradingNameList.SelectedItem == null) return;
    
                // ListViewで選択されている項目を取り出す
                stock_CodeAndName ListItem = (stock_CodeAndName)TradingNameList.SelectedItem;
    
                //  ListViewで選択されている項目をテキストボックスに表示する
                stock_code_box.Text = ListItem.stock_code;
                stock_name_box.Text = ListItem.stock_name;
    
            }
    
            private void ItemSerch_TextChanged(object sender, TextChangedEventArgs e)
            {
                // 検索ボックスへの入力で、ListViewに表示する内容を変更する
    
                // productCode列の値を入力文字でフィルタリングしたリストを作成する
                var filterList_code =
                    CodeAndNames.Where(x => x.stock_code.Contains(ItemSerch.Text)).ToList();
    
                // productName列の値を入力文字でフィルタリングしたリストを作成する
                var filterList_name =
                    CodeAndNames.Where(x => x.stock_name.Contains(ItemSerch.Text)).ToList();
    
                // 2つのリストを結合して、重複のないリストを作る
                var filterList = filterList_code.Union(filterList_name).ToList();
    
                // 作成したリストをItemsSourceに指定する
                TradingNameList.ItemsSource = filterList;
            }
        }
    }

 

kukekko.hateblo.jp