【问题标题】:WPF: DataGrid how can i input multi-line textWPF:DataGrid如何输入多行文本
【发布时间】:2011-02-11 11:42:52
【问题描述】:

伙计们 我想在 DataGridTextColumn 中输入多行文本,我可以使用“enter”来输入多行字符。但我想像 Visual Studio 资源管理器一样使用“shift+enter”,这是我的带有“enter”键的代码。

<DataGridTextColumn Header="Value" Binding="{Binding Value}" Width="*">
  <DataGridTextColumn.ElementStyle>
      <Style TargetType="TextBlock">
         <Setter Property="TextWrapping" Value="Wrap" />
      </Style>
  </DataGridTextColumn.ElementStyle>
  <DataGridTextColumn.EditingElementStyle>
      <Style TargetType="TextBox">
        <Setter Property="TextWrapping" Value="Wrap" />
        <Setter Property="AcceptsReturn" Value="true" />
      </Style>
  </DataGridTextColumn.EditingElementStyle>

【问题讨论】:

    标签: wpf string datagrid input multiline


    【解决方案1】:

    您可以做到这一点的一种方法是使用样式中的 EventSetter 处理 TextBox 上的 KeyDown 事件。我以您的示例为例,删除了样式中的 AcceptsReturn 设置器,并向 EditingElementStyle 添加了一个 KeyDown 处理程序,该处理程序在插入符号所在的位置添加了一个换行符并将 CaretIndex 移动到右侧。

    这是 XAML:

    <DataGridTextColumn Header="Value" Binding="{Binding Value}" Width="*">
        <DataGridTextColumn.ElementStyle>
            <Style TargetType="TextBlock">
                <Setter Property="TextWrapping" Value="Wrap" />
            </Style>
        </DataGridTextColumn.ElementStyle>
        <DataGridTextColumn.EditingElementStyle>
            <Style TargetType="TextBox">
                <Setter Property="TextWrapping" Value="Wrap" />
                <EventSetter Event="KeyDown" Handler="OnTextBoxKeyDown"/>
            </Style>
        </DataGridTextColumn.EditingElementStyle>
    </DataGridTextColumn>
    

    我在一个新的应用程序项目模板的 Window 类中编写了示例,所以这里是整个 Window 的 C# 以及事件处理代码。请注意,我将 Handled 设置为 true 以阻止事件在任何地方冒泡,因为在这种情况下,我不希望将 Return 键作为对编辑行的提交来处理。我认为这实际上是该方法的缺点之一。如果您在应用程序中与用户输入进行复杂的交互,则停止事件的冒泡/隧道传输很容易变成逻辑炸弹。但是,如果您只有一个这样的特殊情况,那还不错。因此,与所有事情一样,随着使用它的 UI 部分的增长,请谨慎使用。

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new List<Thing>
            {
                new Thing { Value = "Some text" },
                new Thing { Value = "More text" + Environment.NewLine + " second line" },
                new Thing { Value = "Another value" }
            };
        }
    
        private void OnTextBoxKeyDown(object sender, KeyEventArgs e)
        {
            if (Key.Return == e.Key && 
                0 < (ModifierKeys.Shift & e.KeyboardDevice.Modifiers))
            {
                var tb = (TextBox)sender;
                var caret = tb.CaretIndex;
                tb.Text = tb.Text.Insert(caret, Environment.NewLine);
                tb.CaretIndex = caret + 1;
                e.Handled = true;
            }
        }
    }
    
    public class Thing
    {
        public string Value { get; set; }
    }
    

    要考虑的另一件事是,如果已按下插入键并且您处于覆盖输入模式,您可能希望行为有所不同。也许在这种情况下,下一个字符应该被新行替换。但是 Visual Studio 2010 中的资源编辑器似乎对插入键没有反应(它也没有将文本显示为多行)。但我认为给出这个例子,你可以扩展它以与插入键一起工作。希望这有帮助,祝你好运!

    【讨论】:

    • 您好,timmyl,非常感谢您的回答。我已经采取了你的方式并尝试从文本框继承,并解决了我的问题,非常非常感谢。
    • 继承很好,因为它可以让您以从类型图中的 TextBox 分支为代价来干净地封装它。封装此事件处理的另一种方法是使用附加属性来添加行为和利用属性更改处理程序为您的属性执行事件订阅/取消订阅。很酷的事情是,这个逻辑不仅可以在 TextBox 中重复使用(就像其他派生控件一样)。最良好的祝愿。
    • 是的,这种方式可以给我提供一些简单的方法来扩展文本框的逻辑,很好。
    【解决方案2】:

    将 TextWrapping 设置为 Wrap 和 AcceptsReturn = True...

    <DataGridTextColumn.EditingElementStyle>
      <Style TargetType="TextBox">
        <Setter Property="TextWrapping" Value="Wrap" />
        <Setter Property="AcceptsReturn" Value="true" />
      </Style>
    </DataGridTextColumn.EditingElementStyle>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-09
      • 2012-06-05
      • 2017-07-03
      • 2019-03-04
      • 1970-01-01
      • 2016-03-23
      • 2020-09-12
      • 1970-01-01
      相关资源
      最近更新 更多