【问题标题】:Binding InputValidation additional data using DependencyProperty使用 DependencyProperty 绑定 InputValidation 附加数据
【发布时间】:2016-03-18 11:22:21
【问题描述】:

这里缺少一些东西:我在数据模板中使用输入验证(有效)并且需要为验证提供额外的数据(无效)。使用“硬编码”值(参见下面代码中的注释)有效,使用绑定无效。

数据模板应用于列表视图中显示的元素(具有“value”、“low_lim”和“high_lim”属性)(这也有效)。我想我只是无法将头绕在绑定上。

也许我只是看久了这个问题。如果我是对的,这是 DP 的某种“视觉树”问题......

任何帮助表示赞赏。

    <DataTemplate DataType="{x:Type OptionA}" >
            <TextBox Width="100" Validation.ErrorTemplate="{StaticResource validationErrorTemplate}">
                <TextBox.Text>
                    <Binding Path="value" UpdateSourceTrigger="PropertyChanged">
                        <Binding.ValidationRules>
                            <val:NumberOptionValidator>
                                <val:NumberOptionValidator.validRange>
                                    <val:Range low_lim="{Binding low_lim}" high_lim="{Binding high_lim}"/>
                                    <!--<val:Range low_lim="1" high_lim="2"/>-->
                                </val:NumberOptionValidator.validRange>
                            </val:NumberOptionValidator>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
    </DataTemplate>

【问题讨论】:

    标签: c# wpf validation binding dependency-properties


    【解决方案1】:

    我建议你在 OptionA 上实现 IDataErrorInfo 而不要使用验证规则。

    根据“何时使用验证规则与 IDataErrorInfo”部分中的https://blogs.msdn.microsoft.com/wpfsdk/2007/10/02/data-validation-in-3-5/,对于“UI 或业务层验证逻辑”:

    使用验证规则: 验证逻辑与数据源分离,可在控件之间重复使用。

    使用IDataErrorInfo:验证逻辑更贴近源代码。

    这里有一些代码可以帮助您入门。

    XAML:

    <Window x:Class="WpfApplication33.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:WpfApplication33"
            xmlns:val="clr-namespace:WpfApplication33"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.DataContext>
            <local:VM />
        </Window.DataContext>
        <Window.Resources>
            <ControlTemplate x:Key="validationErrorTemplate">
                <StackPanel Orientation="Horizontal">
                    <AdornedElementPlaceholder x:Name="textBox"/>
                    <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red"/>
                </StackPanel>
            </ControlTemplate>
            <DataTemplate DataType="{x:Type local:OptionA}">
                <TextBox Width="100"
                         Validation.ErrorTemplate="{StaticResource validationErrorTemplate}"
                         Text="{Binding value, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
            </DataTemplate>
        </Window.Resources>
        <Grid>
            <ListView ItemsSource="{Binding Items}" />
        </Grid>
    </Window>
    

    CS:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows;
    
    namespace WpfApplication33
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    
        public class VM
        {
            public List<OptionA> Items { get; set; }
            public VM()
            {
                Items = new List<OptionA>() {
                    new OptionA() {value=1, low_lim = 0, high_lim = 2 },
                    new OptionA() {value=2, low_lim = 3, high_lim = 4 }, // too low
                    new OptionA() {value=3, low_lim = 2, high_lim = 5 },
                    new OptionA() {value=4, low_lim = 6, high_lim = 9 }, // too low
                    new OptionA() {value=5, low_lim = 0, high_lim = 4 }, // too high
                };
            }
        }
    
        public class OptionA : INotifyPropertyChanged, IDataErrorInfo
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private void OPC(string name) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name)); }
    
            private int _value, _low_lim, _high_lim;
            public int value { get { return _value; } set { if (_value != value) { _value = value; OPC("value"); } } }
            public int low_lim { get { return _low_lim; } set { if (_low_lim != value) { _low_lim = value; OPC("low_lim"); } } }
            public int high_lim { get { return _high_lim; } set { if (_high_lim != value) { _high_lim = value; OPC("high_lim"); } } }
    
            #region IDataErrorInfo
            public string Error
            {
                get
                {
                    return null;
                }
            }
    
            public string this[string columnName]
            {
                get
                {
                    string err = null;
                    if (columnName == "value")
                    {
                        if (value < low_lim || value > high_lim)
                            err = string.Format("Value is out of the range of {0} to {1}.", low_lim, high_lim);
                    }
                    return err;
                }
            }
            #endregion
        }
    }
    

    截图:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-07
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 2011-01-05
      相关资源
      最近更新 更多