WPF:DataGrid如何输入多行文本

时间:2011-02-11 11:42:53

标签: wpf string datagrid input multiline

人 我想将多行文本输入到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>

2 个答案:

答案 0 :(得分:13)

一种方法是使用Style中的EventSetter处理TextBox上的KeyDown事件。我拿了你的例子,删除了样式中的AcceptsReturn setter,并在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>

我在一个新的Application项目模板中在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中的资源编辑器似乎对插入键没有反应(它也不会将文本显示为多行)。但我认为在这个例子中,您可以使用插入键扩展它以使其正常工作。希望这有帮助,祝你好运!

答案 1 :(得分:6)

将TextWrapping设置为Wrap,并将AcceptsReturn设置为True ...

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