Validate user inputs in PropertySheet

876
12
Jump to solution
05-05-2020 11:19 AM
AbelPerez
Occasional Contributor

I followed the sample here ProGuide Custom settings · Esri/arcgis-pro-sdk Wiki · GitHub and have added my own add-in settings to the backstage. I've binded several properties to the UI and it works great. I have a textbox where the user can browse to a folder where our company's data exists. If the user inputs an invalid folder I wanted to change the backcolor of the textbox and set the OK button to disabled until the input is fixed. A similar thing is done with the Layout options.

Ive looked in the community samples and looked at the Pro SDK and cant find anything. Where would I add my validation logic to mimic the existing Layout options?

0 Kudos
1 Solution

Accepted Solutions
GintautasKmieliauskas
Regular Contributor

I have attached bundle of ProjectSettingsView mvvm code of BackStage_PropertyPage sample from Esri ArcGIS Pro samples. It works

View solution in original post

12 Replies
GintautasKmieliauskas
Regular Contributor
AbelPerez
Occasional Contributor

Yes Im aware of the validation binding. Thank You. What I am asking is how we tap into the Pro Settings OK button to disable it when something is not valid.

0 Kudos
GintautasKmieliauskas
Regular Contributor

You can disable OK button  by setting Page IsValid property, like this:

            base.IsValid = false;

AbelPerez
Occasional Contributor

Ok I am able to bind my validation rules to the textbox. It works great! Thanks!.

But now am struggling how to get that result back to the ViewModel so I can update the IsValid of the page.

My XAML looks like this

<TextBox x:Name="txtLayerDir" TextWrapping="Wrap" VerticalAlignment="Top" Margin="10,86,36,0">
<TextBox.Text>
<Binding Path="MyAppDataDir" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<ui:DataPathRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>

In the ViewModel I can initialize to False and I can see that works:

Protected Overrides Function InitializeAsync() As Task

'setup the initial validity of the Page
MyBase.IsValid = False


Return Task.FromResult(0)
End Function

But how do I process updates? Just cant seem to figure that one out.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

In the setter for the MyAppDataDir property in the ViewModel set base.IsValid:

// for example

public string MyAppDataDir
{
get { return _myAppDataDir; }
set
{
SetProperty(ref _myAppDataDir, value, () => MyAppDataDir);
base.IsValid = System.IO.Directory.Exists(value);
}
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
AbelPerez
Occasional Contributor

Wolfgang Kaiser‌ I had something similar but didnt work. I believe its because of the Validity rules. Since the path doesnt exist then the property is never set.

Public Property MyDataDir As String
Get
  Return _myAppDataDir
End Get
Set(ByVal value As String)
  MyBase.IsValid = False
   If SetProperty(_aaAnalystAppDataDir, value, Function() MyAppDataDir) Then
    MyBase.IsModified = True
    MyBase.IsValid = True 'the property passed the validity rules
  Else
    MyBase.IsValid = False
  End If
End Set
End Property

I even changed my XAML to

<Binding Path="MyAppDataDir" UpdateSourceTrigger="PropertyChanged" ValidatesOnExceptions="True" ValidatesOnDataErrors="True" NotifyOnValidationError="True">

0 Kudos
AbelPerez
Occasional Contributor

So now I tried setting Validation.Error="Validation_Error" in my XAML.

Then I put the handler Validation_Error in the code behind the XAML but that's not where I want it correct?

The handler should go in the ViewModel right?

How would I then reference that in my XAML?

Private Sub Validation_Error(sender As Object, e As ValidationErrorEventArgs)
    Debug.Print("there was an error")
End Sub

0 Kudos
GintautasKmieliauskas
Regular Contributor

Hi Abel,

You need to implement IDataErrorInfo to your viewmodel

internal class ProjectSettingsViewModel : Page, IDataErrorInfo.

More info here:

https://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/

You just need to modify content of

public string this[string columnName]

to store each control state and set base.IsValid value.

0 Kudos
AbelPerez
Occasional Contributor

Well I gave it a shot. I spent half a day trying to get this to work and just couldn't. I think I am missing something. The source code in your link is a dead link. Tried other sources but just couldn't get it to work.

0 Kudos