Why is my WPF textbox "kinda" readonly?
Asked Answered
W

5

32

I have a text box in WPF that is part of a datatemplate for a listbox. In that text box I can delete, backspace, spacebar, but I can NOT type in new words, letters or numbers. I CAN paste from notepad though.

What am I missing here?

 <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>
Waligore answered 23/2, 2009 at 18:50 Comment(0)
A
60

I was encountering a problem very similar to this. After doing a little research, I found a similar problem listed in MSDN:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c68d5f3c-c8cc-427d-82e3-6135d075a304/

According to the answer to the post, the problem has to do with WPF and WinForms having two very different ways of handling text input. Fortunately, the post listed above gives the following solution:

When launching the window, use ElementHost.EnableModelessKeyboardInterop(window1). Note that this is a static method - you do not have to instantiate the ElementHost class.

For example,

Window window1 = new Window();
ElementHost.EnableModelessKeyboardInterop(window1);
window1.Show();

This solved the problem for me. Hope this helps.

Amalgam answered 12/3, 2009 at 17:5 Comment(5)
Well, I like your answer better than mine.Waligore
Excellent answer. I realize you don't seem all that active, but I have started a bounty that I will award to you once I am able.Reduplication
Just chiming in to mention another gotcha that can occur when you have WinForms/MFC calling WPF and using ElementHost.EnableModelessKeyboardInterop(wpfwindow). If the WPF window opens another window using Window.Show() then the text box problem will occur there too - each individual window needs the modeless interop enabled. Note that Window.ShowDialog() does not cause the problem.Deuterium
Just an info if you don't find it (just because assembly is not already added). The fully qualified name is System.Windows.Forms.Integration.ElementHost()Yager
Thanks! Trying to call a WPF form in Outlook and this was making me crazy. Ended up just calling myForm.ShowDialog(); instead of myForm.Show(); to fix it.Gesner
P
2

I also found the same behaviour but not when mixing wpf and win forms.

I made a custom combo box that worked fine on its own/in a little test project but when placed in the application it wasnt getting keyboard focus properly when it was clicked on.

The click was being fired but then immediately they textbox lost focus. Again you could paste things in but not type normally.

It turned out (nice one Snoop (http://snoopwpf.codeplex.com/)) that a scrollviewer that a load of combo boxes were in was stealing keyboard focus.

Marking the event as handled stopped this happening and made it work as expected:

    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;
    }
Pusillanimous answered 1/2, 2013 at 10:59 Comment(0)
P
0

I created a simple test app, and I can type new text into the TextBoxes in the 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>

The only difference that I can see between the two is that an ItemTemplate is set on your ListBox, and one isn't on mine. What is the XAML for rADetailEntryLayout?

Prescriptible answered 23/2, 2009 at 20:16 Comment(4)
Maybe I am too much of a WPF noob, but I don't follow your question. The XAML is right in the datatemplate, or am I missing the question?Waligore
I tried changing to using DataType="{x:Type Entities:RADetailEntry}" instead of naming it, and it still doesn't work correctly.Waligore
You specified both an ItemTemplate, and a DataTemplate for your data type. The ItemTemplate will automatically be used for all of the items in the ListBox. Assuming all items are of type RADetailEntity, you don't need both - one or the other should do.Prescriptible
I specified both because I didn't know about setting the DataType="{x:Type Entities:RADetailEntry}". Without that, I had to name the datatemplate, and call it explicitly in the item template. I made the change, to be like your example, but it still fails.Waligore
E
0

Apparently one needs to add a ScrollViewer element with x:Name="PART_ContentHost" to the Border element, see the note at: http://msdn.microsoft.com/en-us/library/ms752068.aspx

Elate answered 13/7, 2009 at 9:49 Comment(0)
B
0

First things first, have you noticed that there is no ItemTemplate set on your Item? second, why have you declared the DataTemplate inside a resource? are you willing to use multiple types on the ItemTemplate? if so you will need a DataTemplateSelector, that will return a specific DataTemplate for the specified type, else if you just need to add the template to this specific Item, replace the ListBox.Resources with ListBox.ItemTemplate and remove the key from the dataTemplate, compile it and there you go.

here is how it should be to work properly:

<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>

Hopes this is still usefull since the long time from the question have been posted...

Burkett answered 4/8, 2009 at 13:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.