20210304のC#に関する記事は2件です。

MaterialDesignのComboBox HasClearButtonの大きさを変更する

はじめに

WPF MaterialDesignは便利なのですが、時々表示が大きすぎたりとやや使い勝手に癖があります。
ComboBoxを使用した際に、選択したものをクリアするために、クリアボタンが表示させることができます。

    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"

    <ComboBox x:Name="GenderComboBox" Width="60" 
                materialDesign:TextFieldAssist.HasClearButton="True"
                ItemsSource="{Binding ItemsGenderValue}" 
                Text="{Binding Gender.Value, UpdateSourceTrigger=PropertyChanged}" 
                materialDesign:HintAssist.Hint="性別"/>

以下のような表示になります
image.png

ただ、このクリアボタンが大きくて、見栄えが良くありません。もう少し小さいほうがいいし、押し間違いしないかと思います。

解決方法

xaml側で何とかできないかと考えましたが、スタイルをかなりいじることになりそうで面倒でした。
ということで、簡単な解決方法ですが、コードビハインドでフォームロード時に変更してしまえというものです。

まず、クリアボタンですが、これはComboBoxのPART_ClearButtonで定義されています。
これをScaleTransformでサイズを指定します。
ただ、これだとちょっと位置ずれが起きたので、クリアボタンのpaddingで調整します。
実際、標準のスタイルでもpaddingで位置調整していたので、この対策で問題ないかと思います。
で、以下が、対策後のコードとなります
ちなみに、この例では、Windowではなく、Prismを使用している関係でUserControlとなっています。

        private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            // ComboBoxのClearButtonを取得します 
            Button genderComboBoxclearButton = GenderComboBox.Template.FindName("PART_ClearButton", GenderComboBox) as Button;

            // ComboBoxのClearButtonの大きさを少し小さめにします 
            ScaleTransform st = new ScaleTransform(0.75,0.75);
            genderComboBoxclearButton.RenderTransform = st;

            // ComboBoxのClearButtonの表示位置を調整します
            genderComboBoxclearButton.Padding = new System.Windows.Thickness(2, 4, -5, -4);
        }

修正前
image.png
修正後
image.png

ほんのちょっとの修正ですが、思ったより見やすくなったのではないかと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【C#】改良版:csvやテキストファイルをバイナリーデータで取り込むプログラム

はじめに

過去記事「【C#】csvファイルをバイナリデータで取り込むプログラム」で作成したサンプルプログラムをもとに、CSVやtxtファイルをバイナリーデータでまるごと取り込めるプログラムを作成した。

過去記事URL:https://qiita.com/kohi7777/items/40b9c78ee3ff4de43468

変更点

1.機能を分け、親クラスと子クラスに分割した。
2.取得できるデータをバイナリーデータか文字列か選べるようにした。
3.メソッド間でやりとりしてたバイナリーデータ配列の型をArrayListではなくコレクションクラスに変えて使いやすくした。
4.コンマで分割する機能は一旦削除。

入力csvデータ

test.csv
1,りんご,赤
2,バナナ,黄
3,メロン,緑
4,もも,ピンク

サンプルプログラム

親クラス(計算処理クラス)

CSVByteOperation_Base.cs
using System;
using System.Collections.Generic;

namespace test
{
    /// <summary>
    /// CSVバイト操作スーパークラス
    /// </summary>
    class CSVByteOperation_Base
    {
        /// <summary>
        /// バイト配列から位置、長さでバイト配列を取得する
        /// </summary>
        /// <param name="InputData">Byteデータ配列</param>
        /// <param name="StartPoint">開始ポイント</param>
        /// <param name="Length">取得したい長さ</param>
        /// <returns></returns>
        protected List<byte> GetByteFromByte(List<byte> InputData, int StartPoint, int Length)
        {
            List<byte> rtnValue;

            if (Length == 0)
                Length = InputData.Count - StartPoint;

            if (Length < 1)
            {
                rtnValue = new List<byte>();
                return rtnValue;
            }

            rtnValue = new List<byte>();

            for (int i = 0; i < Length; i++)
            {
                if (StartPoint + i < InputData.Count)
                    rtnValue.Add(InputData[StartPoint + i]);
            }

            return rtnValue;
        }

        /// <summary>
        /// テキストデータを読み込んでバイト配列を取得する
        /// </summary>
        /// <param name="FilePath">テキストデータのパス</param>
        /// <returns>List型</returns>
        protected List<byte> GetBinaryData(string FilePath)
        {
            List<byte> rtnValue = new List<byte>();

            System.IO.FileStream fs = null;
            System.IO.BinaryReader br = null;

            try
            {
                fs = new System.IO.FileStream(FilePath, System.IO.FileMode.Open);
                br = new System.IO.BinaryReader(fs);

                int Length = (int)fs.Length;

                var ForConvertion = br.ReadBytes(Length);
                fs.Close();

                foreach (var item in ForConvertion)
                {
                    rtnValue.Add(item);
                }
            }
            catch (Exception ex)
            {
                if (br != null)
                    br.Close();

                if (fs != null)
                    fs.Close();

                throw ex;
            }

            return rtnValue;
        }

        /// <summary>
        /// 改行を区切りとして、バイトデータを1行ずつまとめてリストに取得する
        /// </summary>
        /// <param name="InputData"></param>
        /// <returns></returns>
        protected List<List<byte>> DivideLine(List<byte> InputData)
        {
            List<List<byte>> rtnValue = new List<List<byte>>();

            int StartPoint = 0;
            int EndPoint = 0;
            int Length = 0;

            while (EndPoint >= 0)
            {
                EndPoint = SearchCRLF(InputData, StartPoint);

                if (EndPoint < 0)
                {
                    Length = InputData.Count - StartPoint;

                    if (Length <= 0)
                        break;
                }
                else
                    Length = EndPoint - StartPoint;

                var LineData = GetByteFromByte(InputData, StartPoint, Length);

                rtnValue.Add(LineData);

                StartPoint = EndPoint + 1;
            }

            return rtnValue;
        }

        /// <summary>
        /// 読み込みデータからCRLFの位置を取得
        /// </summary>
        /// <param name="InputData">バイト配列</param>
        /// <param name="StartPoint">開始ポイント</param>
        /// <returns></returns>
        protected int SearchCRLF(List<byte> InputData, int StartPoint)
        {
            int EndPoint = -1;

            for (int i = StartPoint; i < InputData.Count - 1; i++)
            {
                if (InputData[i] == 0xD & InputData[i + 1] == 0xA)
                {
                    EndPoint = i + 1;
                    break;
                }
            }

            return EndPoint;
        }
    }
}

子クラス(実行用メソッドクラス)

CSVByteOperation_Method.cs
using System;
using System.Collections.Generic;

namespace test
{
    /// <summary>
    /// CSVバイト操作メソッドクラス
    /// </summary>
    class CSVByteOperation_Method : CSVByteOperation_Base
    {
        private string _FilePath;
        public List<List<byte>> _ByteList;

        /// <summary>
        /// コンストラクタ CSVデータのByte変換とライン区切り
        /// </summary>
        /// <param name="FilePath"></param>
        public CSVByteOperation_Method(string FilePath)
        {
            try
            {
                _FilePath = FilePath;

                GetCSV();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// CSVデータのByte変換とライン区切り
        /// </summary>
        public void GetCSV()
        {
            try
            {
                _ByteList = new List<List<byte>>();

                var BinaryData = GetBinaryData(_FilePath);
                _ByteList = DivideLine(BinaryData);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 読み込んだバイナリーデータリストの行数を取得
        /// </summary>
        /// <returns></returns>
        public int GetDataCount()
        {
            try
            {
                if (_ByteList == null)
                    return 0;

                return _ByteList.Count;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 読み込んだバイナリーデータリストのi番目のラインを取得
        /// </summary>
        /// <param name="index">取得したいインデックス</param>
        /// <returns></returns>
        public List<byte> GetLineData(int index)
        {
            try
            {
                if (_ByteList == null)
                    return null;

                if (index >= _ByteList.Count)
                    return null;

                return _ByteList[index];
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 読み込んだバイナリーデータリストのi番目のラインを文字列で取得
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public string GetLineDataConvertString(int index)
        {
            try
            {
                if (_ByteList == null)
                    return null;

                if (index >= _ByteList.Count)
                    return null;

                var ByteArray = new byte[_ByteList[index].Count];

                for (int i = 0; i < _ByteList[index].Count; i++)
                {
                    ByteArray[i] = _ByteList[index][i];
                }

                return System.Text.Encoding.Default.GetString(ByteArray);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

Programクラス(使い方サンプル)

Program.cs
using System;
using static System.Console;

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            CSVByteOperation_Method csvm = new CSVByteOperation_Method(@"C:\Folder\test.csv");

            for (int i = 0; i < csvm.GetDataCount(); i++)
            {
                WriteLine(csvm.GetLineDataConvertString(i));
            }

            ReadKey();
        }
    }
}

使い方解説

インスタンスを生成するときに、引数にファイルパスを入れる。
すると、コンストラクタでファイルをバイナリーデータに変換し、リストに保持する。
上の使い方サンプルのように、GetDataCountメソッドでループの回数を設定する。
GetLineDataメソッドではバイナリーデータの配列を1行分List型で取得でき、GetLineDataConvertStringメソッドでは1行分を文字列に変換して取得できる。

出力結果

1,りんご,赤
2,バナナ,黄
3,メロン,緑
4,もも,ピンク
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む