BindingExpressionBase.ValidateWithoutUpdate Method

Definition

Runs any ValidationRule objects on the associated Binding that have the ValidationStep property set to RawProposedValue or ConvertedProposedValue. This method does not update the source.

public bool ValidateWithoutUpdate();

Returns

true if the validation rules succeed; otherwise, false.

Examples

The following example demonstrates the scenario that is discussed in the Remarks section. The example enables a user to enter data for a library item and submit the data. The binding for the TextBox named callNum has a ValidationRule associated with it. When the TextBox loses focus, the example calls ValidateWithoutUpdate. When the user clicks the submit button, the example calls UpdateSource to commit the changes. The following XAML creates the user interface for the application.

<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="HeaderedContentControl">
            <Setter Property="Margin" Value="2"/>
            <Setter Property="Focusable" Value="False"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="HeaderedContentControl">
                        <DockPanel LastChildFill="False">
                            <ContentPresenter ContentSource="Header" DockPanel.Dock="Left" 
                              Focusable="False" VerticalAlignment="Center"/>
                            <ContentPresenter ContentSource="Content" Margin="5,0,0,0" 
                              DockPanel.Dock="Right" VerticalAlignment="Center"/>
                        </DockPanel>

                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

</StackPanel.Resources>
    <HeaderedContentControl Header="Title">
        <TextBox Width="150" Text="{Binding Path=Title, Mode=TwoWay}"/>
    </HeaderedContentControl>
    <HeaderedContentControl Header="Due Date">
        <TextBox Width="150" Text="{Binding Path=DueDate, StringFormat=d, Mode=TwoWay}">

        </TextBox>
    </HeaderedContentControl>
    
    <HeaderedContentControl Header="Call Number">
        <TextBox Name="CallNum" Width="150"
                 LostFocus="CallNum_LostFocus"
                 Validation.Error="CallNum_Error">
            <TextBox.Text>
                <Binding xmlns:src="clr-namespace:BindingExpressionBaseValidateWithoutUpdating"
                    Path="CallNumber" Mode="TwoWay"
                    NotifyOnValidationError="True"
                    UpdateSourceTrigger="Explicit">
                    <Binding.ValidationRules>
                        <src:CallNumberRule ValidationStep="ConvertedProposedValue"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    </HeaderedContentControl>

    <Button Click="Button_Click">Submit</Button>
    
    <HeaderedContentControl Header="Title">
        <TextBlock Text="{Binding Path=Title, Mode=TwoWay}"/>
    </HeaderedContentControl>
    
    <HeaderedContentControl Header="Due Date">
        <TextBlock Text="{Binding Path=DueDate, StringFormat=d, Mode=TwoWay}"/>
    </HeaderedContentControl>
    
    <HeaderedContentControl Header="Call Number">
        <TextBlock Text="{Binding CallNumber}"/>
    </HeaderedContentControl>

</StackPanel>

The following example shows the logic for the user interface.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace BindingExpressionBaseValidateWithoutUpdating
{

    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            // Create an object and set it to the window's DataContext.
            LibraryItem item = new LibraryItem("Enter the title",
                    "Enter the call number",  DateTime.Now + new TimeSpan(14, 0, 0, 0));

            this.DataContext = item;
        }

        // Check whether the call number is valid when the
        // TextBox loses foces.
        private void CallNum_LostFocus(object sender, RoutedEventArgs e)
        {
            BindingExpression be = CallNum.GetBindingExpression(TextBox.TextProperty);

            be.ValidateWithoutUpdate();
        }

        // Show the validation error when one occurs.
        private void CallNum_Error(object sender, ValidationErrorEventArgs e)
        {
            if (e.Action == ValidationErrorEventAction.Added)
            {
                MessageBox.Show(e.Error.ErrorContent.ToString());
            }
        }

        // Update the source data object when the user clicks
        // the submit button.
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            BindingExpression be = CallNum.GetBindingExpression(TextBox.TextProperty);

            be.UpdateSource();
        }
    }
}

The following example shows the data object and ValidationRule for the application.

using System;
using System.ComponentModel;
using System.Windows.Controls;
using System.Globalization;

namespace BindingExpressionBaseValidateWithoutUpdating
{
    // LibraryItem implements INotifyPropertyChanged so that the 
    // application is notified when a property changes.  It 
    // implements IEditableObject so that pending changes can be discarded.
    // In this example, the application does not discard changes.
    public class LibraryItem : INotifyPropertyChanged, IEditableObject
    {
        struct ItemData
        {
            internal string Title;
            internal string CallNumber;
            internal DateTime DueDate;
        }

        ItemData copyData;
        ItemData currentData;

        public LibraryItem(string title, string callNum, DateTime dueDate)
        {
            Title = title;
            CallNumber = callNum;
            DueDate = dueDate;
        }

        public string Title
        {
            get { return currentData.Title; }
            set
            {
                if (currentData.Title != value)
                {
                    currentData.Title = value;
                    NotifyPropertyChanged("Title");
                }
            }
        }

        public string CallNumber
        {
            get { return currentData.CallNumber; }
            set
            {
                if (currentData.CallNumber != value)
                {
                    currentData.CallNumber = value;
                    NotifyPropertyChanged("CallNumber");
                }
            }
        }

        public DateTime DueDate
        {
            get { return currentData.DueDate; }
            set
            {
                if (value != currentData.DueDate)
                {
                    currentData.DueDate = value;
                    NotifyPropertyChanged("DueDate");
                }
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #endregion

        #region IEditableObject Members

        public virtual void BeginEdit()
        {
            copyData = currentData;
        }

        public virtual void CancelEdit()
        {
            currentData = copyData;
            NotifyPropertyChanged("");
        }

        public virtual void EndEdit()
        {
            copyData = new ItemData();
        }

        #endregion

    }

    public class CallNumberRule : ValidationRule
    {
        // A valid call number contains a period (.)
        // and 6 characters after the period.
        public override ValidationResult Validate(object value, 
                                         CultureInfo cultureInfo)
        {
            string callNum = (string)value;

            int dotIndex = callNum.IndexOf(".");
            if (dotIndex == -1 || dotIndex == 0)
            {
                return new ValidationResult(false, 
                    "There must be characters followed by a period (.) in the call number.");
            }

            string substr = callNum.Substring(dotIndex + 1);

            if (substr.Length != 6)
            {
                return new ValidationResult(false, 
                    "The call number must have 6 characters after the period (.).");
            }

            return ValidationResult.ValidResult;
        }
    }
}

Remarks

The ValidateWithoutUpdate method enables you to run validation rules on a binding without updating the source of the binding. This is useful when you want to validate user input and update the source at different times in an application.

For example, suppose you have a form to update a data source that contains a submit button. You want to provide feedback to the user if an invalid value is entered before the user attempts to submit the form. You can check the validity of a field by setting the binding's UpdateSourceTrigger property to Explicit and calling ValidateWithoutUpdate when the TextBox loses focus.

Applies to

Produkt Versionen
.NET Framework 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
Windows Desktop 3.0, 3.1, 5, 6, 7, 8, 9, 10