Привязка данных для двух текстовых полей - PullRequest
1 голос
/ 25 октября 2011

У меня есть 2 текстовых поля, каждое в отдельном списке. В первом текстовом поле должны отображаться данные из XML-файла. Поэтому, когда я нажимаю на текстовое поле, данные в первом текстовом поле будут отображаться во втором текстовом поле. Я сделал это, выполняя очень большой круг, получая конкретный объект, когда я щелкаю по нему и добавляю в другой просмотр списка. Есть ли более короткий способ сделать это через связывание по имени элемента в xaml? Мое elementName в textbox1 будет именем для 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>

Ответы [ 2 ]

1 голос
/ 25 октября 2011

Для начала давайте разберемся с NameScoping в WPF.В WPF любые привязки в пределах Templates относятся только к этому Template.Также любой элемент, названный в шаблоне, не будет доступен для Binding.ElementName ссылки вне шаблона.

Так что в вашем случае TextBox headText не может быть указан TextBox *1009* как текстовое поле Aname-scoped под GridViewColumn.CellTemplate.

Также, почему текстовое поле headText находится под ListView?ItemsControls подобно ListBox, ListView, DataGrid не следует использовать в качестве панелей или контейнеров для размещения отдельных элементов.Их намерение - показать несколько предметов.Вместо этого используйте Panel s или 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();
            }
        }
    }

Надеюсь, это поможет.

0 голосов
/ 25 октября 2011

Я не совсем уверен, что происходит с "SelectedText", к которому вы пытаетесь привязаться, но если все, что вы пытаетесь сделать, это отображать текст "lvItems" SelectedItem в вашем TextBox "headText", то должно работать следующее

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...