繁体   English   中英

C# Windows Forms DateTimePicker,如何获取SelectedText、SelectionStart和SelectionLength?

[英]C# Windows Forms DateTimePicker, how to get the SelectedText, SelectionStart, and SelectionLength?

.NET DateTimePicker 有文本,但我不知道如何获取和设置 DateTimePicker 的 SelectionStart、SelectionLength 和 SelectionText 属性。

例如,如何以编程方式 select 日期“2001 年 11 月 17 日”中的 2 天数字? 以及如何以编程方式确定当前选择开始 position?

本质上,我想做的是类似于以下代码:

// Select the day's text
((TextBox)myDateTimePicker).SelectionStart = 3;
((TextBox)myDateTimePicker).SelectionLength = 2;

// Get the text start position
return ((TextBox)myDateTimePicker).SelectionStart;

在此处输入图像描述

以下代码是我的问题的答案。 它源自DateTimePicker 获取焦点字段问题的答案

public event System.EventHandler<EventArgs> Parent_ValueChanged;

public enum DatePart
{
  YEAR,
  MONTH,
  DAY
}

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public DatePart SelectedPart { get; set; }

private DateTime m_PreviousValue = TimeTools.UnixBaseTime;
private bool m_CheckSelectedPart = false;

public void DateTimeField_GotFocus(object sender, EventArgs e)
{
  m_PreviousValue = this.Value;
  m_CheckSelectedPart = true;
  SendKeys.SendWait("{UP}");
  SendKeys.SendWait("{DOWN}");
  m_CheckSelectedPart = false;
}


public void DateTimeField_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
  switch (e.KeyCode)
  {
    case Keys.Space: 
      e.IsInputKey = true;
      break;
    case Keys.Tab:
      m_PreviousValue = this.Value;
      m_CheckSelectedPart = true;
      SendKeys.SendWait("{UP}");
      SendKeys.SendWait("{DOWN}");
      m_CheckSelectedPart = false;

      // Set e.IsInputKey to false to let Windows use the Tab 
      // to go to the previous or next component with TabStop = true
      if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
      {
        // false = exit to the left or up
        e.IsInputKey = !(SelectedPart == DatePart.MONTH);
      }
      else
      { 
        // false = exit to the right or down
        e.IsInputKey = !(SelectedPart == DatePart.YEAR);
      }
      break;
    default: break;
  }
}


public void DateTimeField_KeyDown(object sender, KeyEventArgs e)
{
  // Mimic Delphi's DateTimePicker behavior by advancing to the next part in the format
  // using Space or Tab
  if (e.KeyCode.Equals(Keys.Space) || e.KeyCode.Equals(Keys.Tab))
  {
    if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
    {
      SendKeys.Send("{left}");
    }
    else
    {
      SendKeys.Send("{right}");
    }
  }
}


private void DateTimeField_ValueChanged(object sender, EventArgs e)
{
  if ((m_CheckSelectedPart) && (sender is DateTimePicker dtp))
  {
    TimeSpan change = (dtp.Value - m_PreviousValue);
    var dayChange = Math.Abs(change.Days);
    if (dayChange == 1)
    {
      SelectedPart = DatePart.DAY;
    }
    else if (dayChange >= 365)
    {
      SelectedPart = DatePart.YEAR;
    }
    else
    {
      SelectedPart = DatePart.MONTH;
    }
    m_PreviousValue = dtp.Value;
  }

  // parent's ValueChanged event handler
  Parent_ValueChanged?.Invoke(sender, e);
}

我知道这个问题被问了很长时间,但它对于下一个仍在寻找暂时未解决的解决方案的人很有用,再次询问应该是一个满足的解决方案,编写和管理的代码更少。

在焦点离开DateTimerPicker控件并稍后返回到它之后,控件会记住哪个部分(日、月或年)具有焦点。 焦点回到那部分。

如何强制焦点回到控件的第一个 per ?

要强制控件忘记哪个部分具有焦点,您可以更改格式,然后再次将其更改回来。 因此,如果将其设置为 Short,请将其设置为 Long,然后再设置为 Short。

诀窍是在焦点通过 Enter 事件返回后执行此操作

所以最好的地方是在 Enter 事件中:

Private Sub DateTimePicker_Enter(sender As Object, e As System.EventArgs) Handles DateTimePicker.Enter

        DateTimePicker.Format = DateTimePickerFormat.Long
        DateTimePicker.Format = DateTimePickerFormat.Short
End Sub

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM