Я не понимаю сообщение об ошибке «Привязка не может быть изменена после ее использования»

У меня есть два текстовых поля, которые мне нужно найти в сетке WPF. Я нашел их обоих. Затем я привязываю текстовые поля к свойствам класса, который использует INotifyPropertyChanged. Первое текстовое поле привязывается правильно. Второй нет. Я попытался создать новое второе текстовое поле и привязать его к исходному свойству второго текстового поля. Теперь я получаю сообщение об ошибке «Привязка не может быть изменена после ее использования». Я попытался очистить привязку с помощью «BindingOperations.ClearAllBindings(textBox02)», но все равно получаю ошибку. Я удалил второе текстовое поле и создал другое. Один раз запустилось без ошибки, а потом ошибка появилась снова. Как добавить IValueConverter к существующей привязке имеет ту же проблему. Я попытался создать новую привязку, но при втором запуске получил ту же ошибку. Я новичок в ВПП. Я не знаю, говорит ли мне ошибка о том, что мне нужно использовать новую привязку, привязку к другому свойству или заменить текстовое поле. Я попробовал все три, но проблема осталась. Коды для различных областей приведены ниже.
Заранее спасибо,

Род Маккей

Создайте текстовые поля:

                chartTraderCustomTextBlockArray[1] = new TextBlock()
                {
                    FontFamily = ChartControl.Properties.LabelFont.Family,
                    FontSize = 13,
                    Foreground = ChartControl.Properties.ChartText,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Margin = new Thickness(5, 20, 5, 5),
                    Name = "txtBlock01",
                    Text = string.Format("{0} ", indicatorRiskValue)
                };

                chartTraderCustomTextBoxArray[0] = new TextBox()
                {
                    FontFamily = ChartControl.Properties.LabelFont.Family,
                    FontSize = 13,
                    Foreground = ChartControl.Properties.ChartText,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Margin = new Thickness(5, 5, 5, 5),
                    Name = "textBox02",
                    Text = string.Format("{0} ", shareQuantity),
                    Height = 20,
                    Width = 240
                };

Я использовал следующий код, чтобы найти текстовые поля:

chartWindow = System.Windows.Window.GetWindow(e.Parent) as NinjaTrader.Gui.Chart.Chart;
chartTraderGrid = (chartWindow.FindFirst("ChartWindowChartTraderControl") as ChartTrader).Content as Grid;
textBox00 = chartTraderGrid.FindFirst("TextBox00") as System.Windows.Controls.TextBox;
textBox02 = chartTraderGrid.FindFirst("TextBox02") as System.Windows.Controls.TextBox;

Ящики найдены правильно. Затем я привязываю текстовые поля к свойствам в классе, который использует INotifyPropertyChanged.

Binding binding = new Binding("Quantity");
binding.Source = noOfShares;
textBox00.SetBinding(TextBox.TextProperty, binding)
Binding binding2 = new Binding("Risk");
binding.Source = noOfShares;
textBox02.SetBinding(TextBox.TextProperty, binding2);

Это источник привязки:

public class NumberOfShares : ObservableObject
{
    private string _risk;
    private string _quantity;
    // Declare the event
    public event PropertyChangedEventHandler PropertyChanged;
    public NumberOfShares()
    {
    }
    public string Risk
    {
        get { return _risk; }
        set
        {
            _risk = value;
            OnPropertyChanged();
        }
    }

    public string Quantity
    {
        get { return _quantity; }
        set
        {
            _quantity = value;
               // Call OnPropertyChanged whenever the property is updated
            OnPropertyChanged();
        }
    }

    // Create the OnPropertyChanged method to raise the event
    // The calling member's name will be used as the parameter.
    protected void OnPropertyChanged([CallerMemberName] string quantity = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(quantity));
    }
}

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string propertyname = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
    }

}

А где код, изменяющий существующую привязку? Похоже, вы не опубликовали полный соответствующий код. Если вы хотите изменить объект Binding, вы должны клонировать его (или просто создать новый экземпляр) и переназначить его. Изменение существующей привязки не допускается, поскольку она запечатывается, как только ей присваивается целевое свойство. Идея состоит в том, что вы можете использовать один экземпляр Binding для установки нескольких привязок.

BionicCode 29.07.2024 10:17

Для каждого использования Binding создает неизменяемый экземпляр BindingExpression, который является фактическим базовым объектом привязки, управляющим соединением между двумя объектами. Если бы вам было разрешено изменять используемую привязку, то платформе также пришлось бы изменить все связанные с ней выражения BindingExpressions. Это может привести к потенциально нежелательным побочным эффектам. Потому что эта модификация изменит ВСЕ привязки, а не только привязку конкретного целевого элемента, который вы хотели изменить. Перфоманс, вероятно, тоже был на уме у автора. Почему это так, мы можем только догадываться.

BionicCode 29.07.2024 10:17

С технической точки зрения более важным является тот факт, что BindingExpression является неизменным и что ассоциации не отслеживаются (Binding не запоминает и не наблюдает за всеми созданными им BindingExpressions).

BionicCode 29.07.2024 10:17

Возможно, вместо изменения привязки вам следует изменить значение исходного свойства. Это намного проще и эффективнее, чем изменение/замена привязки.

BionicCode 29.07.2024 10:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что у вас просто случайная ошибка при наборе текста. Правильно было бы:

Binding binding = new Binding("Quantity");
binding.Source = noOfShares;
textBox00.SetBinding(TextBox.TextProperty, binding)
Binding binding2 = new Binding("Risk");
// binding.Source = noOfShares; Invalid line
binding2.Source = noOfShares; // Correct variant
textBox02.SetBinding(TextBox.TextProperty, binding2);

Чтобы избежать подобных ошибок, используйте инициализаторы:

Binding binding = new Binding("Quantity")
{
    Source = noOfShares
};
textBox00.SetBinding(TextBox.TextProperty, binding)

Binding binding2 = new Binding("Risk")
{
    Source = noOfShares
};
textBox02.SetBinding(TextBox.TextProperty, binding2);

Бионический код. Спасибо за объяснение. Я искал везде, о чем только мог подумать, и ваш ответ, наконец, объясняет процесс привязки до такой степени, что я понимаю. EldHasp Тут немного смутился. Я продолжал искать логическую ошибку, и это была опечатка. Спасибо

Member 12823749 29.07.2024 22:24

Отличные глаза... ;)

BionicCode 29.07.2024 23:01

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