I have built an add-in to select features from a layer.
There are two TextBoxes on the panel, MultiStageCountValue, which signifies the number of features to be selected, and MultistagePercentageValue, which signifies the percentage of features to be selected. If the user types in the number of features, the code-behind will calculate the percentage of features, updating the MultistagePercentageValue textbox. If the user types in a value for the percentage of features, the code-behind will update the value for the MultiStageCountValue textbox. It also recalculates the actual percentage, since I only allow for integers to be typed into either field (for example, 33% of 76 features is 25 features, which is actually 32.89% of the features)
This is the code for each textbox in the xaml file. I use the value from the MultiStageCountValue textbox in a query in my ViewModel code, using the Binding variable MultistageCount.
<TextBox x:Name="MultistageCountValue"
Text="{Binding MultistageCount}"
PreviewTextInput="NumericTextBox_PreviewTextInput"
TextChanged="MultistageCountValue_TextChanged"/>
<TextBox x:Name="MultistagePercentageValue"
Text="{Binding MultistagePercentage}"
TextChanged="MultistageCountValue_TextChanged"
PreviewTextInput="NumericTextBox_PreviewTextInput"
LostFocus="MultistagePercentageValue_LostFocus"/>
I use the same code for the TextChanged event for both textboxes, which does some validation and updates the MultistagePercentageValue textbox when I change the MultiStageCountValue textbox value.
private void MultistageCountValue_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textbox = sender as TextBox;
if (textbox.Name == "MultistageCountValue")
{
MultistagePercentageValue.Text = ((double)int.Parse(textbox.Text) / NumberofFeatures * 100).ToString("F");
}
// other validation code
}
I have code for when the MultistagePercentageValue textbox loses focus so that the MultiStageCountValue textbox only gets updated when the user is done typing in the percentage
private void MultistagePercentageValue_LostFocus(object sender, RoutedEventArgs e)
{
TextBox textbox = sender as TextBox;
MultistageCountValue.Text = (float.Parse(textbox.Text) / 100 * NumberofFeatures).ToString("F0");
}
In my testing, the MultistageCount value gets updated correctly if I type in the MultiStageCountValue textbox or when I type in the MultistagePercentageValue TextBox and then click in the MultiStageCountValue textbox.
However, if I type in the MultistagePercentageValue TextBox and tab out of the text box, while the MultiStageCountValue textbox will get updated, the MultistageCount value does not get updated and the query uses the previous value.
Why doesn't MultistageCount get updated when the focus is lost by tabbing out of the textbox versus clicking outside it?
Solved! Go to Solution.
Hi @KenBuja
Have you looked into using WPF Notifications to allow the text box UI to update?
I have attached a simple dockpane sample with text boxes to illustrate this.
You set the binding in the xaml for text boxes like this:
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding SelectionCount}" .../>
Then in your View Model:
private int _selectionCount;
public int SelectionCount
{
get => _selectionCount;
set
{
SetProperty(ref _selectionCount, value); //Magic happens here - notification
...
}
}
This is instead of the TextChanged event that you code in the code behind.
Thanks
Uma
The solution @UmaHarano provides is a good one. If I do another update on the code, I'll use that.
I was able to resolve my issue with my code by specifying the Binding class's UpdateSourceTrigger property. The default value for the Text property is LostFocus, so I had to specify it as PropertyChanged.
<TextBox x:Name="MultistageCountValue"
Text="{Binding MultistageCount, UpdateSourceTrigger=PropertyChanged}"
PreviewTextInput="NumericTextBox_PreviewTextInput"
TextChanged="MultistageCountValue_TextChanged"/>
Hi @KenBuja
Have you looked into using WPF Notifications to allow the text box UI to update?
I have attached a simple dockpane sample with text boxes to illustrate this.
You set the binding in the xaml for text boxes like this:
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding SelectionCount}" .../>
Then in your View Model:
private int _selectionCount;
public int SelectionCount
{
get => _selectionCount;
set
{
SetProperty(ref _selectionCount, value); //Magic happens here - notification
...
}
}
This is instead of the TextChanged event that you code in the code behind.
Thanks
Uma
Thanks for your reply. I'll dig into this.
Please note that you're using a beta version in your testing. When I opened it, it couldn't run since it was targeting ArcGIS Pro 3.5
Good catch. I updated the zip to point to Pro 3.4.
The solution @UmaHarano provides is a good one. If I do another update on the code, I'll use that.
I was able to resolve my issue with my code by specifying the Binding class's UpdateSourceTrigger property. The default value for the Text property is LostFocus, so I had to specify it as PropertyChanged.
<TextBox x:Name="MultistageCountValue"
Text="{Binding MultistageCount, UpdateSourceTrigger=PropertyChanged}"
PreviewTextInput="NumericTextBox_PreviewTextInput"
TextChanged="MultistageCountValue_TextChanged"/>