WPF:如何捕获ListView中嵌入的文本框中的选定文本

时间:2009-09-03 18:25:50

标签: wpf listview textbox wpf-controls

我正在尝试在嵌入listView的TextBox中获取所选文本。这看起来很容易,但我找不到一个优雅的解决方案。

当我点击“创建规则”菜单项时,我想获得菜单项所在的TextBox。

我感谢任何帮助!我花了太多时间在这上面......

...                                                                                    - >                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               ...

我想让代码背后的文字像这样......

    private void CreateRuleMenuItem_Click(object sender, RoutedEventArgs e)
    {
        TextBox txtBox = // ???
        string selectedText = txtBox.selectedText;

3 个答案:

答案 0 :(得分:0)

这是一个模板化的控制吗?如果没有,您应该能够添加名称标记x:Name="txtTextbox",然后直接解决,txtTextBox.SelectedText

由于这是一个模板化控件,因此您无法通过名称直接访问。

因此,在您的代码隐藏中,您可以使用类似下面的方法,它将找到指定特定类型(TextBox)的元素的第一个Parent。将以下方法放入帮助程序类或现有代码中:

    /// <summary>
    /// Finds a parent of a given item on the visual tree.
    /// </summary>
    /// <typeparam name="T">The type of the queried item.</typeparam>
    /// <param name="child">A direct or indirect child of the
    /// queried item.</param>
    /// <returns>The first parent item that matches the submitted
    /// type parameter. If not matching item can be found, a null
    /// reference is being returned.</returns>
    public static T TryFindParent<T>(this DependencyObject child)
        where T : DependencyObject
    {
        //get parent item
        DependencyObject parentObject = GetParentObject(child);

        //we've reached the end of the tree
        if (parentObject == null) return null;

        //check if the parent matches the type we're looking for
        T parent = parentObject as T;
        if (parent != null)
        {
            return parent;
        }
        else
        {
            //use recursion to proceed with next level
            return TryFindParent<T>(parentObject);
        }
    }

然后您只需在代码事件处理程序中执行此代码:

        MenuItem menuItem = sender as MenuItem;
        if(menuItem!=null)
        {
            TextBox textBox = menuItem.TryFindParent<TextBox>();
            if(textBox!=null)
            {
                string selectedText = textBox.SelectedText;
            }
        }

这个方法在我的很多项目中很有用,所以我创建了一个UIHelper类,我将这些类型的东西放入...

祝你好运,

杰森

答案 1 :(得分:0)

非常感谢您的及时帮助!它是一个模板控件,如下所示。

                        <GridViewColumn Header="Content">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBox Text="{Binding Path=record_content}" Width="800">
                                        <TextBox.ContextMenu>
                                            <ContextMenu>
                                                <MenuItem Name="CreateRuleMenuItem"
                                                          Header="Create Rule"
                                                          Click="CreateRuleMenuItem_Click"/>
                                                <MenuItem Name="DeleteRuleMenuItme" 
                                                          Header="Delete Rule" 
                                                          Click="DeleteRuleMenuItme_Click"/>
                                            </ContextMenu>
                                        </TextBox.ContextMenu>
                                    </TextBox>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>

答案 2 :(得分:0)

在这种情况下,我建议您使用MVVM和数据绑定。

我看到你有一个带有“record_content”属性的类XXX,该属性绑定到TextBox的Text属性。 (我认为您省略了Mode = TwoWay Binding选项以确保TextBox中的更改更改了record_content属性值)

您可以添加一个recordContentSelectedText属性,绑定到TextBox的SelectedText属性:

<TextBox [...] SelectedText="{Binding recordContentSelectedText,Mode=TwoWay}"/>

TextBox的datacontext是XXX的一个实例,其中record_content包含TextBox内容....而且ContextMenu及其项目具有相同的DataContext!

如果数据绑定正确更新了属性值,那将非常简单:

var data = this.DataContext as XXX;
var selectedText = this.recordContentSelectedText;

仅当您的DataContext仅绑定到列表中的一个TextBox时,它才有效。否则,TextBox选择的文本同步将作为副作用发生(我不知道你是否理解我的意思,但它可能是一个问题,取决于你期望从你的应用程序的行为)