Почему мое текстовое поле WPF доступно только для чтения?
У меня есть текстовое поле в WPF, которое является частью таблицы данных для списка. В этом текстовом поле я могу удалять, возвращать, пробел, но НЕ могу вводить новые слова, буквы или цифры. Я МОГУ вставить из блокнота.
Что мне здесь не хватает?
<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>
Ответов (5)5
Я столкнулся с проблемой, очень похожей на эту. Проведя небольшое исследование, я обнаружил аналогичную проблему, указанную в 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();
Это решило проблему для меня. Надеюсь это поможет.
Я также обнаружил такое же поведение, но не при смешивании форм wpf и win.
Я сделал настраиваемое поле со списком, которое отлично работало само по себе / в небольшом тестовом проекте, но когда оно было помещено в приложение, оно не получало фокус клавиатуры должным образом при нажатии.
Щелчок был запущен, но сразу же текстовое поле потеряло фокус. Опять же, вы можете вставлять что-то, но не печатать нормально.
Оказалось (замечательный Snoop ( http://snoopwpf.codeplex.com/ )), что средство просмотра прокрутки, в котором находилась масса полей со списком, крадет фокус клавиатуры.
Пометка события как обработанного остановила это и заставила его работать должным образом:
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;
}
Я создал простое тестовое приложение и могу ввести новый текст в текстовые поля в 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>
Единственное различие, которое я вижу между ними, заключается в том, что в ItemTemplate
вашем ListBox установлен один, а в моем нет. Для чего нужен XAML rADetailEntryLayout
?
По-видимому, нужно добавить элемент ScrollViewer с x: Name = "PART_ContentHost" к элементу Border, см. Примечание по адресу: http://msdn.microsoft.com/en-us/library/ms752068.aspx
Перво-наперво, заметили ли вы, что для вашего предмета не задан шаблон 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>
Надеюсь, что это все еще полезно, так как долгое время с момента публикации вопроса ...