【问题标题】:Why is my WPF textbox "kinda" readonly?为什么我的 WPF 文本框“有点”只读?
【发布时间】:2010-10-09 09:27:00
【问题描述】:

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

【问题讨论】:

    标签: wpf .net-3.5


    【解决方案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();
    

    这解决了我的问题。希望这会有所帮助。

    【讨论】:

    • 好吧,我比我更喜欢你的回答。
    • 优秀的答案。我知道你似乎并不那么活跃,但我已经开始了一项赏金活动,一旦我有能力,我将奖励给你。
    • 只是插话提一下当 WinForms/MFC 调用 WPF 并使用 ElementHost.EnableModelessKeyboardInterop(wpfwindow) 时可能发生的另一个问题。如果 WPF 窗口使用 Window.Show() 打开另一个窗口,那么文本框问题也会在那里发生 - 每个单独的窗口都需要启用无模式互操作。请注意,Window.ShowDialog() 不会导致问题。
    • 如果你没有找到它只是一个信息(只是因为尚未添加程序集)。完全限定名称是 System.Windows.Forms.Integration.ElementHost()
    • 谢谢!试图在 Outlook 中调用 WPF 表单,这让我抓狂。最后只是调用 myForm.ShowDialog();而不是 myForm.Show();修复它。
    【解决方案2】:

    我也发现了相同的行为,但在混合 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;
        }
    

    【讨论】:

      【解决方案3】:

      我创建了一个简单的测试应用程序,我可以在 ListBox 的 TextBoxes 中输入新文本:

      <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 上,而一个不在我的。 rADetailEntryLayout 的 XAML 是什么?

      【讨论】:

      • 也许我是一个 WPF 菜鸟太多了,但我不听你的问题。 XAML 就在数据模板中,还是我错过了问题?
      • 我尝试更改为使用 DataType="{x:Type Entities:RADetailEntry}" 而不是命名它,但它仍然无法正常工作。
      • 您为数据类型指定了 ItemTemplate 和 DataTemplate。 ItemTemplate 将自动用于 ListBox 中的所有项目。假设所有项目都是 RADetailEntity 类型,您不需要两者都需要 - 一个或另一个应该做。
      • 我同时指定了两者,因为我不知道如何设置 DataType="{x:Type Entities:RADetailEntry}"。没有它,我必须命名数据模板,并在项目模板中显式调用它。我做了改变,就像你的例子一样,但它仍然失败。
      【解决方案4】:

      显然需要在 Border 元素中添加一个带有 x:Name="PART_ContentHost" 的 ScrollViewer 元素,请参阅注释:http://msdn.microsoft.com/en-us/library/ms752068.aspx

      【讨论】:

        【解决方案5】:

        首先,你有没有注意到你的 Item 上没有设置 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>
        

        希望这仍然有用,因为问题已经发布了很长时间......

        【讨论】:

          猜你喜欢
          • 2015-11-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-26
          • 2011-06-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多