【问题标题】:Data binding for two textbox两个文本框的数据绑定
【发布时间】:2011-10-25 01:40:00
【问题描述】:

我有 2 个文本框,每个都在不同的列表视图中。第一个文本框应该显示来自 xml 文件的数据。因此,当我单击文本框时,第一个文本框中的数据将显示在第二个文本框中。我通过做一个非常大的回合来做到这一点,当我单击它并附加到另一个列表视图时获取特定对象。有没有更短的方法通过 xaml 中的元素名称绑定来做到这一点?我在 textbox1 中的 elementName 将是 textbox2 的名称。我尝试这样做,但我不确定我的路径应该是什么?

很抱歉没有包含我的 xaml。

<Window x:Class="GridViewTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
    xmlns:local="clr-namespace:GridViewTest"
    Title="MainWindow" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="541" d:DesignWidth="858" SizeToContent="WidthAndHeight">
<Window.Resources>
    <local:PacketList x:Key="PacketList"/>
    <local:BindableSelectionTextBox x:Key="BindableSelectionTextBox"/>
</Window.Resources>
<Grid Height="500" Width="798">
    <Grid.RowDefinitions>
        <RowDefinition Height="142*" />
        <RowDefinition Height="145*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="234*" />
        <ColumnDefinition Width="233*" />
    </Grid.ColumnDefinitions>
    <ListView ItemsSource="{Binding}" x:Name="lvItems" Grid.RowSpan="2" Grid.ColumnSpan="2">
        <ListView.View>
            <GridView AllowsColumnReorder="True">
                <GridViewColumn Header="Header" Width="200">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <TextBox Name ="A" Tag="Header" Text="{Binding SelectedText, Path=headerObj.headervalue}" PreviewMouseLeftButtonUp="Handle_Click"
                                         IsReadOnly="True" BorderThickness="0" >
                                </TextBox>
                            </Grid>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>
    <ListView Margin="0,245,0,8" Grid.ColumnSpan="2" Grid.RowSpan="2" >
        <TextBox  Name="headText" Text="{Binding SelectedText,ElementName=A}"/>
    </ListView>    
</Grid>

【问题讨论】:

  • 这两个文本框是否在同一个容器/用户控件/窗口中?
  • 是的,它们在同一个容器/用户控件/窗口中
  • 已发布。我的 textBox A 绑定到类 Packet 的可观察集合。我的类 Packet 由一个包含字符串的头类组成。所以我想要实现的是当我点击TextBox A时,里面的任何数据都会出现在文本框headText中,当我选择headText中的文本时,A中的相应部分也会被选中。我得到了我正在使用的这个可绑定的文本框类,但我不确定如何将它绑定到我的文本框 A 或文本框 headText。
  • 这是您的重复帖子。为什么不更新之前的帖子? stackoverflow.com/questions/7873438/selected-text-in-textbox
  • @AngelWPF 哦,这是关于绑定部分的。上一篇文章是关于所选文本的。但我仍然无法让选定的文本生效。

标签: c# wpf


【解决方案1】:

首先让我们对 WPF 中的NameScoping 进行一些教育。在 WPF 中,Templates 中的任何绑定都仅限于 Template。此外,模板内命名的任何元素都不能用于模板外的Binding.ElementName 引用。

因此,在您的情况下,TextBox A 不能被 TextBox headText 引用,因为文本框 A 的名称范围在 GridViewColumn.CellTemplate 下。

还有为什么headText 文本框在ListView 下? ItemsControlsListBoxListViewDataGrid 不应用作面板或容器来承载单个元素。他们的目的是展示多个项目。请改用Panels 或ContentControl

   <Grid Margin="0,245,0,8" Grid.ColumnSpan="2" Grid.RowSpan="2" >
       <TextBox  Name="headText" Text="{Binding SelectedText,ElementName=A}"/>
   </Grid>

   <ContentControl Margin="0,245,0,8" Grid.ColumnSpan="2" Grid.RowSpan="2" >
       <TextBox  Name="headText" Text="{Binding SelectedText,ElementName=A}"/>
   </ContentControl>

现在要在两个文本框之间同步选择,请使用以下技巧...

XAML

    <TextBox Name="SelectionSource"
             Tag="{Binding ElementName=SelectionTarget}"
             SelectionChanged="SelectionSource_SelectionChanged" />
    <TextBox Name="SelectionTarget"
             Text="{Binding SelectedText, ElementName=SelectionSource,
                            Mode=TwoWay, UpdateSourceTrigger=Explicit}" />

代码背后...

    private void SelectionSource_SelectionChanged(object sender, RoutedEventArgs e)
    {
        var targetTextBox = ((TextBox) sender).Tag as TextBox;
        if (targetTextBox != null)
        {
            var bndExp
                = BindingOperations.GetBindingExpression(
                    targetTextBox, TextBox.TextProperty);

            if (bndExp != null)
            {
                bndExp.UpdateTarget();
            }
        }
    }

如果您使用的是 MVVM,则在附加行为中处理此 SelectionSource_SelectionChanged 事件。

编辑 2:

现在,如果一个文本框是 ListBox 模板的一部分而另一个在模板之外,则使用内容控制技巧...

XAML:

   <Window.Resources>      
    <TextBox x:Key="SelectionTarget"
             Text="{Binding Tag.SelectedText,
                            RelativeSource={RelativeSource Self},
                            Mode=TwoWay,
                            UpdateSourceTrigger=Explicit}" />
  </Window.Resources>

  <StackPanel>
     <ListBox>
        <ListBox.ItemsSource>
            <x:Array Type="{x:Type System:String}">
                <System:String>Test String 1</System:String>
                <System:String>Test String 2</System:String>
                <System:String>Test String 3</System:String>
            </x:Array>
        </ListBox.ItemsSource>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBox Name="SelectionSource"
                         Text="{Binding Path=., Mode=TwoWay}" 
                         Tag="{StaticResource SelectionTarget}"
                         SelectionChanged="SelectionSource_SelectionChanged" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <ContentControl Content="{StaticResource SelectionTarget}">           
    </ContentControl>

</StackPanel>

代码背后

    private void SelectionSource_SelectionChanged(
       object sender, RoutedEventArgs e)
    {
        var targetTextBox
             = ((TextBox) sender).Tag as TextBox;
        if (targetTextBox != null)
        {
            targetTextBox.Tag = (TextBox) sender;

            var bndExp
                = BindingOperations.GetBindingExpression(
                    targetTextBox, TextBox.TextProperty);

            if (bndExp != null)
            {
                bndExp.UpdateTarget();
            }
        }
    }

希望这会有所帮助。

【讨论】:

  • ohhhh 我不知道 2 个模板之间的元素之间的绑定。这是一个很好的例子!非常感谢!!!!
  • 在这种情况下,有什么方法可以实现其中一个文本框作为表格单元格的文本框和另一个文本框?
【解决方案2】:

我不太确定您尝试绑定到的“SelectedText”发生了什么,但如果您想要做的只是在“headText”文本框中显示“lvItems”SelectedItem 文本,那么以下应该可以工作

<TextBox Name="headText" Text="{Binding ElementName=lvItems, Path=SelectedItem.headerObj.headervalue}" />

您还需要更改您的 TextBox "A" 绑定。

<TextBox Name ="A" Tag="Header" Text="{Binding headerObj.headervalue}" IsReadOnly="True" BorderThickness="0" >
</TextBox>

假设 headerObj 是 Packet 类的一个属性,而 headervalue 是它的一个属性,而 headervalue 是您希望绑定到的值。

“headText”中的文本将在 SelectedItem 更改时更新(而不是在单击 TextBox 时)。

【讨论】:

    猜你喜欢
    • 2011-09-30
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 2013-03-21
    相关资源
    最近更新 更多