2019/04/16

[macOS] vim 常用命令

終端機理要編輯檔案時,vim是非常好用的工具,這裡紀錄常用的命令避免忘記

vim 命令分成兩種:鍵盤命令鍵、命令列指令

vim的啟動方式:

vim
啟動vim編輯器,同時顯示空白的新編輯畫面

vim 檔案名稱
啟動vim編輯器,並開啟指定的檔案

鍵盤命令鍵:

i 進入編輯模式,編輯模式下才可以修改檔案的內容

esc 取消指令或退出編輯模式

命令列指令:

:w 
存檔

:w 新檔案名稱 
另存新檔

:q 
不存檔直接退出vim

:wq 
存檔後退出vim

[Android Studio 3] adb 常用命令

這裡單純紀錄曾經使用過的命令,避免忘記

使用adb在手機外部超作(未shell進手機)

adb shell 登入目前唯一連接的手機

adb devices 查詢目前有連接的手機

adb pull /手機目錄位置/檔案名稱 /電腦目錄位置/ 把手機的檔案複製到電腦上
這個功能用最多的地方是在檢查sqlite的檔案,sqlite檔案位置:
/data/data/專案名稱/databases/sqlite file
檔案位置範例:/data/data/com.test.test1/databases/Data1.db3
完整命令範例:adb pull /data/data/com.test.test1/databases/Data1.db3 /Users/use/

手機內部操作(已shell進手機)

cd 目錄名稱 切換目錄

ls 顯示目前所在目錄的所有資料

exit 離開手機

2019/04/15

[Android Studio 3] ADB 登入emulator 模擬器 取得 ROOT權限

第一步
這是最重要的一步,建立模擬機時必須選擇不支援Play Stone的系統

 這個就不支援play stone可以放心的使用

 這個有支援play stone是沒辦法取得root權限的

第二步
模擬機開啟開發人員模式,並開啟USB偵錯

第三步
使用adb工具輸入命令開啟root權限
adb工具不必連線進入模擬器,只要確保當下只有模擬器啟動,沒有其他真實手機接入電腦就可以了

開啟root命令
先輸入 adb root
如果回傳 restarting adbd as root 代表成功
接者輸入 adb remount
就可以取得root權限登入模擬機了

2018/01/11

[C#] DateGridView 使用 ComboBox 與 DateTimePicker

這一篇主要是針對 https://nonfu.blogspot.tw/2017/12/c-dategridview-datetimepicker.html 所併發出來的想法與程式碼改進 主要就是讓 DataGridView 能使用 DateTimePicker 與 ComboBox 並改進不足之處。

最終完成的成果如下方的圖

程式碼如下:

public partial class DataGridViewEx:System.Windows.Forms.DataGridView
{
 private Point MyPoint;
 private Control parentCTL;
 private ComboBox dtCombo;
 private DateTimePicker dtPicker;

 /// 紀錄可編輯的欄位名稱
 private StringDictionary ColmmEdit;

 /// 紀錄要使用日期資料的欄位名稱
 private StringDictionary ColmmDate;

 /// 紀錄要使用的下拉欄位名稱
 private StringDictionary ColmmCombo;

 public DataGridViewEx() : base()
 {
  this.EditMode = DataGridViewEditMode.EditProgrammatically;
  if (!DesignMode)
  {
   MyPoint = new Point();
   ColmmEdit = new StringDictionary();
   ColmmDate = new StringDictionary();
   ColmmCombo = new StringDictionary();

   this.Disposed += DataGridViewEx_Disposed;
   this.CellClick += DataGridViewEx_CellClick;
   this.CellEnter += DataGridViewEx_CellClick;
   this.EditingControlShowing += DataGridViewEx_EditingControlShowing;

   FirstSetDataTimePicker();
   FirstSetComboBox();

   this.AllowUserToAddRows = true;
   this.AllowUserToDeleteRows = true;
   this.AllowUserToOrderColumns = false;
   this.AllowUserToResizeColumns = false;
   this.AllowUserToResizeRows = false;
  }
 }

 private void DataGridViewEx_Disposed(object sender, EventArgs e)
 {
  if (!DesignMode)
  {
   dtPicker.Dispose();
   dtCombo.Dispose();
  }
 }
       
 /// 設定可編輯的欄位
 public void SetColmmEditName(string NameValue)
 {
  if(!ColmmEdit.ContainsKey(NameValue))
  {
   ColmmEdit.Add(NameValue, NameValue); 
  }
 }

 /// 設定要使用DateTimePicker的欄位
 public void SetColmmDateName(string NameValue)
 {
  if (!ColmmDate.ContainsKey(NameValue))
  {
   ColmmDate.Add(NameValue, NameValue);
  }
 }

 /// 設定要使用ComboBox的欄位
 public void SetColmmComboName(string NameValue)
 {
  if (!ColmmCombo. ContainsKey(NameValue))
  {
   ColmmCombo.Add(NameValue, NameValue);
  }
 }

 /// 檢查欄位是否可以編輯
 private void DataGridViewEx_CellClick(object sender, DataGridViewCellEventArgs e)
 {
  if(this.Rows.Count>0)
  {
   if ((e.RowIndex> -1) && (e.ColumnIndex > -1))
   {
     if (ColmmEdit.ContainsKey(this.Columns[e.ColumnIndex].Name))
     {
      this.BeginEdit(true);
     }
     else
     {
      this.EndEdit();
     }
    }
    else
    {
     this.EndEdit();
    }
   }
  }

 /// 判斷是否使用DateTimePicker、ComboBox
 private void DataGridViewEx_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
 {
  if (this.Rows.Count > 0)
  {
   if (this.CurrentCell.RowIndex > -1 && this.CurrentCell.ColumnIndex > -1)
   {
    if (parentCTL == null)
    {
     parentCTL = e.Control.Parent;
     parentCTL.Controls.Add(dtPicker);
     parentCTL.Controls.Add(dtCombo);
    }
    MyPoint.X = e.Control.Location.X - e.Control.Margin.Left < 0 ? 0 : e.Control.Location.X - e.Control.Margin.Left;
    MyPoint.Y = e.Control.Location.Y - e.Control.Margin.Top < 0 ? 0 : e.Control.Location.Y - e.Control.Margin.Top;
                    
    if (ColmmDate.ContainsKey(this.Columns[this.CurrentCell.ColumnIndex].Name))
    {
     SetDataTimePickerView(ref e);
    }
    else
    {
     MyPoint.X = 0;
     MyPoint.Y = 0;
     dtPicker.Location = MyPoint;
     dtPicker.Visible = false;
    }

    if (ColmmCombo.ContainsKey(this.Columns[this.CurrentCell.ColumnIndex].Name))
    {
     SetComboBoxView(ref e);
    }
    else
    {
     MyPoint.X = 0;
     MyPoint.Y = 0;
     dtCombo.Location = MyPoint;
     dtCombo.Visible = false;
    }
   }
  }
 }

 private void FirstSetComboBox()
 {
  dtCombo = new ComboBox();
  dtCombo.Name = "ComboBox1";
  dtCombo.FlatStyle = FlatStyle.Flat;

  dtCombo.Font = this.AlternatingRowsDefaultCellStyle.Font;
  dtCombo.Visible = false;
  dtCombo.SelectedIndexChanged += new EventHandler(ComboBox1_SelectedIndexChanged);
 }

 private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
 {
  this.CurrentCell.Value = ((ComboBox)sender).SelectedItem;
 }

 /// 設定下拉選單內容
 public void SetComboData(string[] Value)
 {
  dtCombo.Items.Clear();
  dtCombo.Items.AddRange(Value);
 }

 private void SetComboBoxView(ref DataGridViewEditingControlShowingEventArgs e)
 {
  dtCombo.Size = this.CurrentCell.Size;
  dtCombo.Location = MyPoint;
  if (e.Control.Text != "")
  {
   dtCombo.SelectedItem = e.Control.Text;
  }
  else
  {
   dtCombo.SelectedIndex = -1;
  }          
  
  e.Control.Visible = false;
  dtCombo.Visible = true;
 }

 /// DateTimePicker的日期資料回寫欄位
 private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
 {
   this.CurrentCell.Value = ((DateTimePicker)sender).Value.ToString("yyyy/MM/dd");
 }

 private void FirstSetDataTimePicker()
 {
  dtPicker = new DateTimePicker();
  dtPicker.Name = "dateTimePicker1";
  dtPicker.Format = DateTimePickerFormat.Custom;
  dtPicker.CustomFormat = "yyyy/MM/dd";
  dtPicker.MinDate = DateTime.Parse("1920/01/01");
  dtPicker.CalendarFont = this.AlternatingRowsDefaultCellStyle.Font;
  dtPicker.Visible = false;
  dtPicker.ValueChanged += new EventHandler(dateTimePicker1_ValueChanged);
 }

 private void SetDataTimePickerView(ref DataGridViewEditingControlShowingEventArgs e)
 {
  dtPicker.Size = this.CurrentCell.Size;
  dtPicker.Location = MyPoint;
  dtPicker.MaxDate = DateTime.Now;
  if (e.Control.Text != "")
  {
   dtPicker.Value = DateTime.ParseExact(e.Control.Text, dtPicker.CustomFormat, null);
  }
  else
  {
   dtPicker.Value = DateTime.Now;
   this.CurrentCell.Value = dtPicker.Value.ToString("yyyy/MM/dd");
  }
  
   e.Control.Visible = false;
   dtPicker.Visible = true;
 }

}

2017/12/17

[C#] DateGridView 使用 DateTimePicker 輸入日期

使用DateGridView常常遇到需要輸入日期的情境,對使用者來說DateTimePicker是很直覺的輸入方式
但是原始的DateGridView並不支援DateTimePicker的使用,以往為了解決這個問題,我都是參考微軟
的這一篇 https://msdn.microsoft.com/zh-tw/library/7tas5c80.aspx 進行修改
最近看到這一篇 https://dotblogs.com.tw/danking/2014/11/13/147294 讓我興起改寫
DateGridView的想法。

對於改寫控制項還不是很了解要如何使用在專案的人,可以參考我的另一篇文https://nonfu.blogspot.tw/2017/11/c-checkbox.html

public partial class DataGridViewEx:System.Windows.Forms.DataGridView
{
  // 紀錄可編輯的欄位名稱
  private StringDictionary ColmmEdit;

  // 紀錄要使用日期資料的欄位名稱
  private StringDictionary ColmmDate;

  public DataGridViewEx() : base()
  {
    this.EditMode = DataGridViewEditMode.EditProgrammatically;
    if (!DesignMode)
    {
      ColmmEdit = new StringDictionary();
      ColmmDate = new StringDictionary();
      this.Disposed += DataGridViewEx_Disposed;
      this.CellClick += DataGridViewEx_CellClick;
      this.EditingControlShowing += DataGridViewEx_EditingControlShowing;          
     }
  }

  // 刪除資料清單
  private void DataGridViewEx_Disposed(object sender, EventArgs e)
  {
    if (!DesignMode)
    {
      ColmmEdit.Clear();
      ColmmDate.Clear();
    }
  }
       
  // 設定可編輯的欄位
  public void SetColmmEditName(string NameValue)
  {
    if(!ColmmEdit.ContainsKey(NameValue))
    {
      ColmmEdit.Add(NameValue, NameValue); 
    }
  }

  // 設定要使用DateTimePicker的欄位
  public void SetColmmDateName(string NameValue)
  {
    if (!ColmmDate.ContainsKey(NameValue))
    {
      ColmmDate.Add(NameValue, NameValue);
    }
  }

  // 檢查欄位是否可以編輯
  private void DataGridViewEx_CellClick(object sender, DataGridViewCellEventArgs e)
  {
    if ((e.RowIndex > -1) || (e.ColumnIndex > -1))
    {

      if (ColmmEdit.ContainsKey(this.Columns[e.ColumnIndex].Name))
      {
        this.BeginEdit(true);
      }
      else
      {
        this.EndEdit();
      }

    }
  }

  // DateTimePicker的日期資料回寫欄位
  private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
  {
    this .CurrentCell.Value = ((DateTimePicker)sender).Value.ToString("yyyy/MM/dd");
  }

  // 判斷是否適用DateTimePicker的欄位
  private void DataGridViewEx_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
  {
    if (this.CurrentCell.ColumnIndex > -1)
    {
      Control parentCTL = e.Control.Parent;

      if(ColmmDate.ContainsKey(this.Columns[this.CurrentCell.ColumnIndex].Name))
      {
        DateTimePicker dtPicker = new DateTimePicker();
        dtPicker.Name = "dateTimePicker1";
        dtPicker.Size = this .CurrentCell.Size;
        dtPicker.Format = DateTimePickerFormat.Custom;
        dtPicker.CustomFormat = "yyyy/MM/dd";

        dtPicker.Location = new Point(
                                      e.Control.Location.X - e.Control.Margin.Left < 0 ? 0 : e.Control.Location.X - e.Control.Margin.Left,
                                      e.Control.Location.Y - e.Control.Margin.Top < 0 ? 0 : e.Control.Location.Y - e.Control.Margin.Top);

        if (e.Control.Text != "")
        {
          dtPicker.Value = DateTime.ParseExact(e.Control.Text, dtPicker.CustomFormat, null);
        }
        else
        {
          dtPicker.Value = DateTime.Now;
          this.CurrentCell.Value = dtPicker.Value.ToString("yyyy/MM/dd");
        }

        e.Control.Visible = false;

        foreach (Control tmpCTL in parentCTL.Controls)
        {
          if (tmpCTL.Name == dtPicker.Name) parentCTL.Controls.Remove(tmpCTL);
        }

        parentCTL.Controls.Add(dtPicker);
        dtPicker.ValueChanged += new EventHandler(dateTimePicker1_ValueChanged);              
      }
      else
      {
        foreach (Control tmpCTL in parentCTL.Controls)
        {
          if (tmpCTL.Name == "dateTimePicker1")
          {
           parentCTL.Controls.Remove(tmpCTL);
          }
        }
      }
    }
  }
}

2017/11/29

[C#] 自訂CheckBox勾選區域

CheckBox自訂勾選範圍太小,一直都是常見的使用者抱怨問題
最常見的作法就是使用使用者控制項來模擬一個CheckBox工具
其實我知道還有一個方法就是直接改寫CheckBox的原始碼
奈何在下才疏學淺,一直都不知道重何下手,而網路上也一直找不到好的參考資料
最近偶然發現了一篇改寫CheckBox的方法,當然要趕緊記錄下來。

資料來源:http://inpega.blogspot.tw/2015/02/ccheckbox.html
主要程式碼都不是我所寫的,我只做了一點調整,為了怕以後找不到資料特複製於此,有任何侵權請通知我,我會立即刪除!

public partial class CheckBoxEx : System.Windows.Forms.CheckBox { public override string Text { get { return base.Text; } set { base.Text = value; Size size = TextRenderer.MeasureText(value, Font); if (Width < size.Width + ClientSize.Height) Width = size.Width + ClientSize.Height; } } public override Font Font { get { return base.Font; } set { base.Font = value; Size size = TextRenderer.MeasureText(Text, value); if (Width < size.Width + ClientSize.Height) Width = size.Width + ClientSize.Height; } } protected override void OnPaint(PaintEventArgs e) { int h = ClientSize.Height; Rectangle rc = new Rectangle(new Point(0, 0), new Size(h, h)); e.Graphics.Clear(Parent.BackColor); ControlPaint.DrawCheckBox( e.Graphics, rc, this.Checked ? ButtonState.Checked : ButtonState.Normal ); SizeF size = e.Graphics.MeasureString(Text, Font); e.Graphics.DrawString( Text, this.Font, new SolidBrush(Color.Black), new PointF(h, size.Height < h ? (h - size.Height) / 2 : 0) ); h = 0; e.Dispose(); } }

補充:

改寫Form控制項,不建議在UserControl、CustomControl 這兩個類型上撰寫,這兩個類型容易發生編譯上的錯誤
建議直接在空的Class類別上開發,開發後其他專案就可以直接在空具箱裡使用。

把改寫的控制項放入工具箱步驟:
1.

2.

直接選擇已編譯完成的新控制項物件即可。


2017/11/13

SD 記憶卡規格說明

SD Card 又或者叫SD記憶卡,是需多3C設備用來儲存資料的媒介。
購買SD Card時,往往會被複雜的規格弄得不知所措,特地整理一下規格資料方便以後查詢。

以下資料與圖片來源:SD 協會 https://www.sdcard.org



1.容量標準:規範記憶卡的容量上限與檔案系統
SD標準–容量上限為2GB,使用FAT 12與FAT 16檔案系統。
SDHC標準–容量介於2GB至32GB間,使用 FAT32檔案系統。
SDXC標準–容量介於32GB至2TB間,使用exFAT檔案系統。
2.記憶卡尺寸:規範記憶卡的尺寸大小與可使用的容量標準
SD
V
V
V
miniSD
V
V
microSD
V
V
V

3.速度標準:購買記憶卡最關鍵的規格,規範記憶卡需要達到的傳輸標準。

速度標誌位置


速度標誌分類

三種速度分類之間沒有相對應的關係。

傳輸速率表


影像解析度與建議使用的速度標誌