I have 2 textboxes that I need to find in a WPF grid. I've found both of them. I then bind the the textboxes to properties in a class that uses INotifyPropertyChanged. The first textbox binds correctly. The second does not. I tried creating a new second text box and binding it to the original 2nd textbox property. I now receive error 'Binding cannot be changed after it has been used'. I tried clearing the binding using 'BindingOperations.ClearAllBindings(textBox02)' but still get the error. I deleted the 2nd textbox and created another. It ran once without the error and then the error reappeared.
How to add IValueConverter to an existing Binding
has the same problem. I tried creating a new binding but get the same error on 2nd run.
I'm very new to WFP. I don't know if the error is telling me that I need to use a new binding, bind to a different property, or replace the textbox. I've tried all three and still have the problem. Code for the various areas are below.
Thanks in advance,
Rod McKay
Create the textboxes:
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
};
I used the following code to find the text boxes:
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;
The boxes are found correctly. I next bind the textboxes to properties in a class that uses 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);
This is the binding source:
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));
}
}
I think you just have a random typing error. Correct would be:
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);
In order to avoid this kind or error, use initializers:
Binding binding = new Binding("Quantity")
{
Source = noOfShares
};
textBox00.SetBinding(TextBox.TextProperty, binding)
Binding binding2 = new Binding("Risk")
{
Source = noOfShares
};
textBox02.SetBinding(TextBox.TextProperty, binding2);