Validation Styles and Documents

Apr 12, 2010 at 5:04 PM

Hello!

AvalonDock is a wonderful tool and I appreciate that someone took the time to create it and publish it for the rest of us.

I'm having an issue with Validation Styles and document switching.  If I create a WPF application that uses AvalonDock and multiple documents and use normal WPF validation in those documents, the default validation style (e.g. a red border around a TextBox) goes away when I switch to a different document and then switch back to the document with the validation error.

To recreate this problem, just create a new WPF application (.Net 3.5) with AvalonDock (1.2.26910) called AvalonTest and then replace the Window1.xaml code with this code:

<Window x:Class="AvalonTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AvalonTest"
    Title="Window1" Height="600" Width="800" xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock">
    <Grid>
        <ad:DockingManager x:Name="_dockingManager">
            <ad:DocumentPane x:Name="documentsHost">
                <ad:DocumentContent Title="Form1" IsCloseable="False">
                    <Grid VerticalAlignment="Top" HorizontalAlignment="stretch">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Margin="3">Field1</Label>
                        <TextBox x:Name="txtField1" Grid.Column="1" Margin="3">
                            <TextBox.Text>
                                <Binding Path="Field1" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
                                    <Binding.ValidationRules>
                                        <local:IntegerOnlyRule/>
                                    </Binding.ValidationRules>
                                </Binding>
                            </TextBox.Text>
                        </TextBox>
                    </Grid>
                </ad:DocumentContent>
                <ad:DocumentContent Title="Form2" IsCloseable="False">
                    <Grid VerticalAlignment="Top" HorizontalAlignment="stretch">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Label Grid.Column="0" Margin="3">Field2</Label>
                        <TextBox x:Name="txtField2" Grid.Column="1" Margin="3">
                            <TextBox.Text>
                                <Binding Path="Field2" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
                                    <Binding.ValidationRules>
                                        <local:IntegerOnlyRule/>
                                    </Binding.ValidationRules>
                                </Binding>
                            </TextBox.Text>
                        </TextBox>
                    </Grid>
                </ad:DocumentContent>
            </ad:DocumentPane>
        </ad:DockingManager>
    </Grid>
</Window>

Then replace Window1.xaml.cs code with this:

using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using AvalonDock;

namespace AvalonTest
{
    public partial class Window1 : Window
    {
        private string _field1 = string.Empty;
        public string Field1
        {
            get { return _field1; }
            set { _field1 = value; }
        }

        private string _field2 = string.Empty;
        public string Field2
        {
            get { return _field2; }
            set { _field2 = value; }
        }

        public Window1()
        {
            InitializeComponent();
            this.DataContext = this;
        }
    }

    public class IntegerOnlyRule : ValidationRule
    {

        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            int number;

            if (!int.TryParse((string)value, out number))
            {
                return new ValidationResult(false, "Illegal characters - only integers allowed");
            }
            else
            {
                return new ValidationResult(true, null);
            }
        }
    }

}

Compile the app and run it.  Steps to re-create:

  1. Add non-integer values into the TextBox on the Active Document so you can observe the red border around the TextBox
  2. Select the other document to make it the Active Document
  3. Select the first document where you put values into the TextBox and you'll see the red border is gone

If you debug into the code, you will see that the invalid TextBox still indicates that it is invalid, but the default Validation style appears to be gone from the displayed TextBox.

Any help with this would be much appreciated.  Thanks!

Anthony Hargan

Apr 15, 2010 at 8:50 PM

Hello, again!

I'm still somewhat new to WPF and I haven't had time to debug through the AvalonDock source code to try and figure out what's going on with the above, but I have an update.

I wanted to customize the AvalonDock document tabs in my app by adding an icon to the tab if there was invalid data in the UserControl hosted by the DocumentContent object.  I used Ado's tutorial on re-styling the document tabs as an example for implementing my customization.  Lo and Behold, and much to my surprise, after completing the customized re-styling I noticed that the problem reported in this thread was gone.  I could have an input control in an invalid state, switch to another document tab, and then switch back and the invalid style would still be visible on the input control.

So, I'm guessing that the source of this is a styling issue in AvalonDock.  Hope that helps.  If I get the time to do so, I will experiment and research more in order to find the exact cause and a possible fix for the AvalonDock code.

Thanks!

Anthony

Aug 3, 2010 at 4:00 PM

H!

I have the same problem, with this. Could you add the fixing code here ?

Thanks !

GCMartijn