Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation is only displayed on the first WizardPage #1764

Open
sprotty opened this issue Jan 9, 2024 · 1 comment
Open

Validation is only displayed on the first WizardPage #1764

sprotty opened this issue Jan 9, 2024 · 1 comment

Comments

@sprotty
Copy link

sprotty commented Jan 9, 2024

Validation is done correctly on the first page of a wizard the first time it is displayed. If you then go to the next page no validation is displayed on any of the following pages, also if you go back to the first page, it does not re-do the validation.

XAML

<Window x:Class="XceedWizardValidation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:XceedWizardValidation" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" x:Name="window" DataContext="{Binding ElementName=window}">
    <xctk:Wizard Name="Wizard">

        <xctk:WizardPage x:Name="Page1" Title="Page1">
            <StackPanel>
                <TextBlock>This field is always wrong</TextBlock>
                <TextBox Text="{Binding Path=MyTest, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/>

                <TextBlock FontSize="15" Margin="0,50,0,0">Go to the next wizardpage, then come back to this one.</TextBlock>
                <TextBlock FontSize="15">Bug: Validation is only performed on the first page of the wizard the first time it is seen.</TextBlock>
            </StackPanel>
        </xctk:WizardPage>

        <xctk:WizardPage x:Name="Page2" Title="Page2">
            <StackPanel>
                <TextBlock>This field also has an error, but its never displayed.</TextBlock>
                <TextBox Text="{Binding Path=MyOtherTest, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/>
            </StackPanel>
        </xctk:WizardPage>

    </xctk:Wizard>

</Window>

Code behind

public partial class MainWindow : Window, IDataErrorInfo, INotifyPropertyChanged
{
    private string _myTest = "Some Value";
    private string _myOtherTest = "Some Value";

    public MainWindow()
    {
        InitializeComponent();
    }

    public string MyTest
    {
        get { return _myTest; }
        set
        {
            _myTest = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyTest)));
        }
    }


    public string MyOtherTest
    {
        get { return _myOtherTest; }
        set
        {
            _myOtherTest = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyOtherTest)));
        }
    }

    #region IDataErrorInfo Implementation
    public string Error { get { return ""; } }

    public string this[string columnName]
    {
        get
        {
            if (columnName == nameof(MyTest))
                return "Its all wrong, try harder.";
            if (columnName == nameof(MyOtherTest))
                return "Its all wrong, try harder.";
            return "";
        }
    }
    #endregion

    public event PropertyChangedEventHandler? PropertyChanged;
}

image

After re-visiting the page

image

@XceedBoucherS
Copy link
Collaborator

Hi,

We can reproduce the issue. Thank you for your sample code.
The problem is that all the bindings are evaluated when the XAML is read at the startup. So switching pages do not refresh the bindings.

Here's a workaround:
Define your own Wizard and override the OnCurrentPageChanged to clear the binding errors and update the binding source:

`public class MyWizard : Wizard
{
protected override void OnCurrentPageChanged( WizardPage oldValue, WizardPage newValue )
{
if( ( newValue != null ) && newValue.Content is FrameworkElement element )
{
for( var i = 0; i < VisualTreeHelper.GetChildrenCount( element ); i++ )
{
var childVisual = VisualTreeHelper.GetChild( element, i );

    var localPropertyValues = childVisual.GetLocalValueEnumerator();
    while( localPropertyValues.MoveNext() )
    {
      if( localPropertyValues.Current.Value is BindingExpression bindingExpression )
      {
        if( bindingExpression.HasError )
        {
          Validation.ClearInvalid( bindingExpression );
          bindingExpression.UpdateSource();
        }
      }
    }
  }
}

base.OnCurrentPageChanged( oldValue, newValue );

}
}`

We will try to add this kind of fix for release v4.7.
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants