首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在UserControl中显示验证错误

在UserControl中显示验证错误
EN

Stack Overflow用户
提问于 2010-11-13 03:44:23
回答 2查看 11.1K关注 0票数 13

我不确定为什么验证状态没有反映在我的用户控件中。我抛出了一个异常,但由于某种原因,控件没有显示验证state...When,我在MainPage上使用了一个标准的Textbox (在我的例子中,它现在已经被注释掉了),它显示了错误状态,不知道为什么它没有包装。

我已经精简了它,所以基本上它是一个包装了TextBox的用户控件。我遗漏了什么??

MyUserControl XAML:

代码语言:javascript
复制
<UserControl x:Class="ValidationWithUserControl.MyUserControl"
    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"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox x:Name="TextBox"/>
    </Grid>
</UserControl>

背后的MyUserControl代码:

代码语言:javascript
复制
public partial class MyUserControl : UserControl
{
    public MyUserControl()
    {
        InitializeComponent();

        this.Loaded += new RoutedEventHandler(MyUserControl_Loaded);
        this.TextBox.Unloaded += new RoutedEventHandler(TextBox_Unloaded);
    }

    public string Value
    {
        get { return (string)base.GetValue(ValueProperty); }
        set { base.SetValue(ValueProperty, value); }
    }

    public static DependencyProperty ValueProperty =
        DependencyProperty.Register(
        "Value",
        typeof(string),
        typeof(MyUserControl),
        new PropertyMetadata(null));

    private void MyUserControl_Loaded(object sender, RoutedEventArgs e)
    {
        this.TextBox.SetBinding(TextBox.TextProperty, new Binding()
        {
            Source = this,
            Path = new PropertyPath("Value"),
            Mode = BindingMode.TwoWay,
            ValidatesOnExceptions = true,
            NotifyOnValidationError= true
        });  
    }

    private void TextBox_Unloaded(object sender, RoutedEventArgs e)
    {
        this.TextBox.ClearValue(TextBox.TextProperty);
    }
}

我的MainPage XAML:

代码语言:javascript
复制
<Grid x:Name="LayoutRoot" Background="LightBlue">
    <StackPanel>
        <uc:MyUserControl x:Name="UC" Value="{Binding Path=Value, Mode=TwoWay}" Height="20" Width="100" />
        <!--TextBox x:Name="MS" Text="{Binding Path=Value, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" Height="20" Width="100" /-->
    </StackPanel>
</Grid>

我的MainPage代码背后:

代码语言:javascript
复制
public partial class MainPage : UserControl
{
    private Model model;
    //private Model model2;

    public MainPage()
    {
        InitializeComponent();
        this.model = new Model("UC");
        //this.model2 = new Model("MS");
        this.UC.DataContext = this.model;
        //this.MS.DataContext = this.model2;
    }
}

我的模型:

代码语言:javascript
复制
public class Model
{
    public Model(string answer)
    {
        this.answer = answer;
    }

    private string answer;
    public string Value
    {
        get
        {
            return this.answer;
        }
        set
        {
            if (!String.IsNullOrEmpty(value))
                this.answer = value;
            else
                throw new Exception("Error");
        }
    }
}
EN

回答 2

Stack Overflow用户

发布于 2018-12-20 04:34:58

您应该能够回显直接绑定到用户控件文本框的依赖属性。这将像父视图中的绑定一样拾取验证错误。在您的MyUserControl_Loaded函数中:

代码语言:javascript
复制
var valueBinding = BindingOperations.GetBindingBase(this, ValueProperty);
if (valueBinding != null) TextBox.SetBinding(TextBox.TextProperty, valueBinding);
票数 3
EN

Stack Overflow用户

发布于 2016-12-13 19:14:31

如果有人来为这个问题寻找一个好的解决方案(请阅读:“不是用VBA语言编写的并且完整的”),我基于@UserControl_Black_蓝精灵在C#中的回答写了一个base class (虽然我只用无外观控件测试过,但不知道它是否适用于UserControls):

代码语言:javascript
复制
namespace MyApplication.Controls
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;

    public abstract class ControlBaseWithValidation : Control, INotifyDataErrorInfo
    {
        public ControlBaseWithValidation()
        {
            // remove the red border that wraps the whole control by default
            Validation.SetErrorTemplate(this, null);
        }

        public delegate void ErrorsChangedEventHandler(object sender, DataErrorsChangedEventArgs e);

        public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

        public bool HasErrors
        {
            get
            {
                var validationErrors = Validation.GetErrors(this);
                return validationErrors.Any();
            }
        }

        public IEnumerable GetErrors(string propertyName)
        {
            var validationErrors = Validation.GetErrors(this);
            var specificValidationErrors =
                validationErrors.Where(
                    error => ((BindingExpression)error.BindingInError).TargetProperty.Name == propertyName).ToList();
            var specificValidationErrorMessages = specificValidationErrors.Select(valError => valError.ErrorContent);
            return specificValidationErrorMessages;
        }

        public void NotifyErrorsChanged(string propertyName)
        {
            if (ErrorsChanged != null)
            {
                ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
            }
        }

        protected static void ValidatePropertyWhenChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            ((ControlBaseWithValidation)dependencyObject).NotifyErrorsChanged(dependencyPropertyChangedEventArgs.Property.Name);
        }
    }
}

使用ControlBaseWithValidation类作为无外观控件的基类,而不是Control类,并在要验证的任何依赖属性上添加ValidatePropertyWhenChangedCallback回调作为PropertyChangedCallback

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4168438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档