简体   繁体   English

WPF中的绑定验证

[英]Binding Validation in WPF

I am jumping into Binding Validation for the first time in WPF. 我是第一次在WPF中进入绑定验证。 I was using the tutorial guides in the Microsoft Docs for validating data entered into a textbox. 我正在使用Microsoft Docs中的教程指南来验证输入到文本框中的数据。 I believe I understand it and followed the process correctly however the validation is still not working. 我相信我理解并正确执行了该过程,但是验证仍然无法进行。 I am not sure if the Binding on the textbox is wrong or if something is amiss with my ValidationRule. 我不确定文本框上的绑定是否错误,或者ValidationRule是否存在问题。 Any help would be appreciated. 任何帮助,将不胜感激。

Below is the class with the validator rule. 下面是带有验证器规则的类。

class NumberCansValidationRule : ValidationRule
{
    private int _min;
    private int _max;

    public int Min
    {
        get { return _min; }

        set { _min = value; }
    }

    public int Max
    {
        get { return _max; }

        set { _max = value; }
    }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        int numCans = 0;

        try
        {
            if (((string)value).Length > 0)
            {
                numCans = Int32.Parse((string)value);
            }
        }
        catch (Exception e)
        {
            return new ValidationResult(false, "Illegal characters or " + e.Message);
        }


        if ((numCans < Min) || (numCans > Max))
        {
            return new ValidationResult(false, "Number of cans must be between: " + Min + " - " + Max + ".");
        }
        else
        {
            return new ValidationResult(true, null);
        }
    }
}

Here is my main class. 这是我的主班。

public partial class MainWindow : Window
{
    public ObservableCollection<Drinks> SomeDrinks { get; private set; }

    public MainWindow()
    {
        InitializeComponent();

        SomeDrinks = new ObservableCollection<Drinks>();

        SomeDrinks.Add(new Drinks("Soda", "Pepsi", 5));         
        SomeDrinks.Add(new Drinks("Tea", "Lemon", 3));
        SomeDrinks.Add(new Drinks("Caffinated", "Coffee", 0));
        SomeDrinks.Add(new Drinks("Other", "Water", 0));

        DrinksListBox.ItemsSource = SomeDrinks;
        DrinkTypeComboBox.ItemsSource = SomeDrinks;
    }

    private void CmdDeleteDrink_Clicked(object sender, RoutedEventArgs e)
    {
        Button cmd = (Button)sender;

        if (cmd.DataContext is Drinks deleteDrink)
        {
            SomeDrinks.Remove(deleteDrink);
        }
    }

    private void CmdAddDrink_Clicked(object sender, RoutedEventArgs e)
    {
        string typeSelection = ((Drinks)DrinkTypeComboBox.SelectedItem).Type;

        int canNum = Int32.Parse(NumberCansTextBox.Text);

        SomeDrinks.Add(new Drinks(typeSelection, DrinkNameTextBox.Text, canNum)
        {
            IsUserDefined = true
        });
    }
}

public class Drinks
{
    private string type;
    private string name;
    private int numCans;

    public Drinks(string type, string name, int numCans)
    {
        this.type = type;
        this.name = name;
        this.numCans = numCans;
    }

    public bool IsUserDefined { get; set; }

    public string Type
    {
        get { return type; }

        set
        {
            if (type != value)
            {
                type = value;
            }
        }
    }

    public string Name
    {
        get { return name; }

        set
        {
            if (name != value)
            {
                name = value;
            }
        }
    }

    public int NumberOfCans
    {
        get { return numCans; }

        set
        {
            if (numCans != value)
            {
                numCans = value;
            }
        }
    }
}

My XAML is here. 我的XAML在这里。

<Window x:Class="WpfApp1.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:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVis"/>

    <ControlTemplate x:Key="validationTemplate">
        <DockPanel>
            <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
            <AdornedElementPlaceholder/>
        </DockPanel>
    </ControlTemplate>

    <Style x:Key="textStyleTextBox" TargetType="TextBox">
        <Setter Property="Foreground" Value="#333333" />
        <Setter Property="MaxLength" Value="40" />
        <Setter Property="Width" Value="392" />
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <ListBox x:Name="DrinksListBox" HorizontalAlignment="Center" Height="325" Width="275" Margin="0,0,0,0" VerticalAlignment="Center" Grid.Column="0" ItemsSource="{Binding SomeDrinks}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="0,2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Type}" Width="80"  Margin="0,0,10,0" Grid.Column="0"/>
                    <TextBlock Text="{Binding Name}" Width="80"  Margin="0,0,10,0" Grid.Column="1" HorizontalAlignment="Left"/>
                    <TextBlock Text="{Binding NumberOfCans}" Width="80"  Margin="0,0,10,0" Grid.Column="2" HorizontalAlignment="Left"/>
                    <Button x:Name="DrinkDeleteButton" Content="Delete" Visibility="{Binding Path=IsUserDefined, Converter={StaticResource BoolToVis}}" Click="CmdDeleteDrink_Clicked" HorizontalAlignment="Left" Grid.Column="3"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <TextBox x:Name="DrinkNameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="45" Margin="0,0,0,100" TextWrapping="Wrap" Text="Enter Drink Name" VerticalAlignment="Center" Width="240" FontSize="20" VerticalContentAlignment="Center"/>
    <TextBox x:Name="NumberCansTextBox" Style="{StaticResource textStyleTextBox}" Grid.Column="1" HorizontalAlignment="Left" Height="45" Margin="0,0,0,150" VerticalAlignment="Bottom" Width="240" FontSize="20" VerticalContentAlignment="Center">
        <TextBox.Text>
            <Binding Path="NumberOfCans" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <local:NumberCansValidationRule Min="0" Max="10"/>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <ComboBox x:Name="DrinkTypeComboBox" Grid.Column="1" HorizontalAlignment="Left" Margin="0,47,0,0" VerticalAlignment="Top" Width="240" Height="45" ItemsSource="{Binding Drinks,  Mode=OneWay}" DisplayMemberPath="Type" FontSize="20"/>
    <Button x:Name="AddDrinkButton" Content="Add Drink" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,10,100" VerticalAlignment="Center" Width="100" Height="45" Click="CmdAddDrink_Clicked"/>
</Grid>

Firstly you need to add 首先,您需要添加

<Window.Resources>
    <local:Drinks x:Key="Drink"/>
...
</Window.Resources>
...
<Binding Path="NumberOfCans" UpdateSourceTrigger="PropertyChanged"  Source="{StaticResource Drink}">
...

and constructor without parameters 和没有参数的构造函数

public Drinks()
{
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM