Скопируйте текстовый ящик, включая его привязку

У меня много текстовых полей, распределенных по трем отдельным элементам вкладок, и я хочу дать пользователю возможность выбрать избранные текстовые поля и для удобства отображать их на одном элементе вкладки, который называется «Избранное».

Визуальная часть работает нормально, но я не могу заставить работать привязки, поэтому новое текстовое поле остается пустым.

XAML:

<StackPanel Grid.Row = "3" Grid.Column = "0" x:Name = "SP_TB_DP_ArticleName"     x:Uid = "ArticleName" Style = "{StaticResource FavButton}"  MouseDown = "FavButton_Click" >
   <Label  Content = "ArticleName"  Style = "{StaticResource Heading2}" />
    <Border Background = "Transparent">
      <StackPanel Orientation = "Horizontal">
        <Path Uid = "FavAdd" Style = "{StaticResource Ico-AddFav}" Fill = "Black"/>
        <Path Uid = "FavRem" Style = "{StaticResource Ico-RemFav}" Fill = "Black" Visibility = "Collapsed" />
      </StackPanel>
     </Border>
    </StackPanel>
<TextBox  x:Name = "TB_DP_ArticleName"  Grid.Row = "4" Grid.Column = "0" Grid.ColumnSpan = "2" Style = "{StaticResource Heading3}" Text = "{Binding Article.Name, UpdateSourceTrigger=PropertyChanged}" />

C# привязки

private void FavButton_Click(object sender, MouseButtonEventArgs e)
{
[... creating textbox and label]

//BindingName is the name of the original textbox ie: TB_DP_ArticleName
DependencyObject OriginalTB = (DependencyObject) this.FindName(BindingName);
BindingBase BB = BindingOperations.GetBindingBase(OriginalTB, TextBox.TextProperty);
var oldBind = BB as Binding;

//Clone Method from other question Link see below *
//BindingBase copyBind= CloneBinding(BB, OriginalTB);


 if (OriginalTB != null)
 {
  Binding binding = new Binding();
  binding.Source = this;
  binding.Path = oldBind.Path;
  binding.Mode = BindingMode.OneWay;
  binding.IsAsync = false;
  binding.UpdateSourceTrigger = UpdateSourceTrigger.Default;
  binding.TargetNullValue = "null";
  BindingOperations.SetBinding(tb, TextBox.TextProperty, binding);
  //BindingOperations.SetBinding(tb, TextBox.TextProperty, copyBind);
 }

//Code to add the Textbox to the Grid 
[...]

*) Пробовал cloneMethod от Привязка не имеет метода клонирования, какой эффективный способ его скопировать но это не сработало.

Во время отладки oldBind.Path показывает правильный путь к Article.Name.

Но, в конце концов, программно созданное текстовое поле не будет отображать содержимое исходного текстового поля. Он просто остается пустым.

«отображать их в другой части моего приложения для удобства». Имеет ли эта другая часть приложения тот же DataContext, что и исходные текстовые поля?

Lithium 29.05.2018 14:20

Да. Все в одном Usercontroll. Просто в другом TabItem.

x3Ro 29.05.2018 14:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вместо того, чтобы пытаться дублировать привязки, просто продублируйте элементы управления (с их привязками к данным, но не с их именами), а затем (привяжите к их свойству видимости), который затем отобразит или скроет элемент управления текстовым полем в зависимости от выбора пользователя.

<TextBox  Grid.Row = "4" Grid.Column = "0" Grid.ColumnSpan = "2"
          Style = "{StaticResource Heading2}" 
          Text = "{Binding Article.Name, UpdateSourceTrigger=PropertyChanged}"  
          Visibility = "{Binding AmIVisible_1}" />


<TextBox  Grid.Row = "4" Grid.Column = "0" Grid.ColumnSpan = "2" 
          Style = "{StaticResource Heading3}" 
          Text = "{Binding Article.Name, UpdateSourceTrigger=PropertyChanged}"  
          Visiblity = "{Binding AmIVisible_2}" />

Спасибо за идею другого подхода! Вы имеете в виду дублирование жестко запрограммированным способом? Например, поместить каждое поле данных в этот любимый TabItem, а затем просто переключить видимость? Но разве это довольно неэффективное хранилище неэффективно? Также мне нужно добавить поля данных в двух точках моего кода. И это так много работы для прибл. 300 полей данных. Но все же мне нравится смена точки зрения на это!

x3Ro 29.05.2018 15:22

Я использовал стратегию видимости, и на самом деле это не проблемы с памятью, а задержка отображения, поскольку каждый элемент отображается на экране ... до 40-50 элементов, и задержка не заметна, но в зависимости от размера элементов рисуется, а затем скрывается, вот в чем проблема. 300 дубликатов будут проблемой.

ΩmegaMan 29.05.2018 16:21

Ладно, тогда это может быть не лучшим решением. Разве нет способа программно создавать текстовые поля, такие как: <TextBox Text = "{Binding Path=Text, ElementName=secondTextBox, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}

x3Ro 30.05.2018 08:51
Ответ принят как подходящий

Наконец то я понял!

Мне пришлось установить источник привязки к исходному текстовому полю и установить привязку к тексту. Это не решает проблему на 100%, так как это может быть не самое эффективное решение относительно комментария @AlvinfromDiaspar в Синхронизировать два текстовых поля в WPF Но, в любом случае, для моих целей он работает достаточно хорошо.

Что я изменил:

Binding binding = new Binding("Text");binding.Source = (DependencyObject)this.FindName(BindingName);

Полный фрагмент привязки:

String BindingName = inName.Substring(3);

BindingBase BB = BindingOperations.GetBindingBase(
                 (DependencyObject)this.FindName(BindingName),
                 TextBox.TextProperty);

var oldBind = BB as Binding;

if (BB != null)
{
  //the magic goes here
  Binding binding = new Binding("Text");
  binding.Source = (DependencyObject)this.FindName(BindingName);

  binding.Mode = BindingMode.OneWay;
  binding.IsAsync = false;
  binding.UpdateSourceTrigger = UpdateSourceTrigger.Default;
  binding.TargetNullValue = "null";
  BindingOperations.SetBinding(tb, TextBox.TextProperty, binding);
 }

Другие вопросы по теме