Почему текстовое поле WPF "kinda" только для чтения?
У меня есть текстовое поле в WPF, которое является частью datatemplate для списка. В этом текстовом поле я могу удалить, backspace, пробел, но я не могу вводить новые слова, буквы или цифры. Я могу вставить из блокнота, хотя.
Что мне здесь не хватает?
<ListBox Grid.Column="1"
ItemsSource="{Binding Details}"
VirtualizingStackPanel.VirtualizationMode="Recycling"
HorizontalContentAlignment="Stretch" >
<ListBox.Resources>
<DataTemplate DataType="{x:Type Entities:RADetailEntry}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0" />
<TextBox Grid.Column="1" IsReadOnly="False" IsEnabled="True"
Text="{Binding Path=Description, Mode=TwoWay}" TextWrapping="Wrap"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TextAlignment="Left" />
</Grid>
</DataTemplate>
</ListBox.Resources>
</ListBox>
Ответы
Ответ 1
Я столкнулся с проблемой, очень похожей на это. Проведя небольшое исследование, я нашел аналогичную проблему, указанную в MSDN:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c68d5f3c-c8cc-427d-82e3-6135d075a304/
В соответствии с ответом на сообщение проблема связана с WPF и WinForms, имеющими два самых разных способа обработки ввода текста. К счастью, сообщение, указанное выше, дает следующее решение:
При запуске окна используйте ElementHost.EnableModelessKeyboardInterop(window1). Обратите внимание, что это статический метод - вам не нужно создавать экземпляр класса ElementHost.
Например,
Window window1 = new Window();
ElementHost.EnableModelessKeyboardInterop(window1);
window1.Show();
Это решило проблему для меня. Надеюсь, это поможет.
Ответ 2
Я создал простое тестовое приложение, и я могу ввести новый текст в TextBoxes в ListBox:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:app="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300">
<ListBox ItemsSource="{Binding Details}"
HorizontalAlignment="Stretch"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<ListBox.Resources>
<DataTemplate DataType="{x:Type app:Data}">
<StackPanel Orientation="Horizontal">
<ComboBox />
<TextBox SpellCheck.IsEnabled="True" TextWrapping="Wrap"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Text="{Binding Path=Text, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ListBox.Resources>
</ListBox>
</Window>
Единственное отличие, которое я вижу между двумя, заключается в том, что в вашем ListBox установлен ItemTemplate
, а один - не мой. Что такое XAML для rADetailEntryLayout
?
Ответ 3
По-видимому, нужно добавить элемент ScrollViewer с x: Name= "PART_ContentHost" в элемент Border, см. примечание по адресу: http://msdn.microsoft.com/en-us/library/ms752068.aspx
Ответ 4
Прежде всего, заметили ли вы, что на вашем элементе нет ItemTemplate? во-вторых, почему вы объявили DataTemplate внутри ресурса? готовы ли вы использовать несколько типов на ItemTemplate? если вам понадобится DataTemplateSelector, который вернет определенный DataTemplate для указанного типа, иначе, если вам просто нужно добавить шаблон к этому конкретному элементу, замените ListBox.Resources на ListBox.ItemTemplate и удалите ключ из dataTemplate, скомпилируйте его и там вы идете.
вот как это должно быть правильно работать:
<ListBox Grid.Column="1" ItemsSource="{Binding Path=Details}" VirtualizingStackPanel.VirtualizationMode="Recycling" HorizontalContentAlignment="Stretch" >
<!-- Remove this <ListBox.Resources> -->
<!-- Add this -->
<ListBox.ItemTemplate>
<!-- Remove this <DataTemplate DataType="{x:Type Entities:RADetailEntry}"> -->
<!-- Add this -->
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0" />
<TextBox Grid.Column="1" IsReadOnly="False" IsEnabled="True"
Text="{Binding Path=Description, Mode=TwoWay}" TextWrapping="Wrap"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TextAlignment="Left"
/>
</Grid>
</DataTemplate>
<!-- Remove this </ListBox.Resources> -->
<!-- Add this -->
</ListBox.ItemTemplate>
</ListBox>
Надеется, что это по-прежнему полезно, поскольку долгое время с вопроса было опубликовано...
Ответ 5
Я также нашел такое же поведение, но не при смешивании форм wpf и win.
Я создал собственный комбинированный блок, который отлично работал сам по себе/в небольшом тестовом проекте, но когда он был помещен в приложение, он не получал правильную фокусировку клавиатуры, когда на него нажимали.
Щелчок был уволен, но сразу же они потеряли фокус. Снова вы можете вставлять вещи, но не печатать нормально.
Оказалось (хороший Snoop (http://snoopwpf.codeplex.com/)), что scrollviewer, в котором загружались комбо-боксы, заключался в краже фокуса клавиатуры.
Отмечая событие как обработанное, остановило это и сделало его работающим, как ожидалось:
private void ClickOnStack(object sender, MouseButtonEventArgs e)
{
//do other stuff with click
_textBox.Focus();
//note this is key to stop things like scrollviewers nicking focus
e.Handled = true;
}