Один из способов сделать это - обработать событие KeyDown в TextBox с помощью EventSetter в вашем стиле.Я взял ваш пример, удалил установщик AcceptsReturn в стиле и добавил обработчик KeyDown к EditingElementStyle, который добавляет новую строку в том месте, где была каретка, и перемещает 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 из нового шаблона проекта приложения, так что вот C # для всего Window с кодом обработки событий.Обратите внимание, что я установил Handled в true, чтобы событие не всплывало в любом месте, так как я не хочу, чтобы в этом случае ключ Return обрабатывался как фиксация в строке редактирования.Я думаю, что это на самом деле один из недостатков подхода.Остановка барботирования / туннелирования события - это то, что, если у вас есть сложные взаимодействия с пользовательским вводом в вашем приложении, может легко превратиться в логическую бомбу.Но это не так плохо, если у вас есть только один особый случай, подобный этому.Так же как и во всем, используйте осторожно, так как часть вашего пользовательского интерфейса, использующего это, растет.
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, похоже, не реагирует на клавишу вставки (он также не отображает текст как многострочный).Но я думаю, что, учитывая этот пример, вы можете расширить его для правильной работы с помощью клавиши вставки.Надеюсь это поможет. Удачи!