一种实现方式是通过在样式中使用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,以防止事件在任何地方冒泡,因为我不希望在这种情况下将返回键处理为对编辑行的提交。我认为这实际上是这种方法的缺点之一。停止事件的冒泡/隧道是一个容易变成逻辑炸弹的事情,特别是当您的应用程序与用户输入有复杂的交互时。但如果您只有一个特殊情况,那么也不是太糟糕。所以像任何东西一样,随着使用这个部分的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中的资源编辑器似乎不会对插入键作出反应(它也不会将文本显示为多行)。但我认为,根据此示例,您可以扩展它以使其与插入键配合得很好。希望这有所帮助-祝您好运!