VS2013 WPF walidacja danych

0

Witajcie

mam dziwny problem, mianowicie, na podstawie niniejszego artykułu

https://mndevnotes.wordpress.com/2012/12/01/wpf-walidacja-danych/

próbuje przeprowadzić walidację textbox-ów. Niestety kody nie działają.
Gdzieś przeczytałem, że w Visual Studio 2013 należy zaznaczyć coś debug-erze. System to Win 7 x64.

Za każdą odpowiedź, vielen Dank.

pzdr

0

Pokaż kod bo zapewne tam jest jakiś błąd a nie w VS.

0

Kod jest w linku.

Dziwne zachowanie polega na tym, że waliduje dwa pola z tego tutorialu firstname i lastname.
Pierwszy rodzaj walidacji w ogóle nie działa, drugi rodzaj działa na zasadzie wpisuje litery, potem je kasuje, pokazuje się błąd i okno "Exceptions" zaznaczam Thrown dla Common Language Runtime Exceptions wciskam Ok i Continoue i wtedy zaznacza się na pomarańczowo ramka textbox-a z wykrzyknikiem.

pzdr

0

Nadal nie widzę Twojego kodu. Czy czytałeś komentarze ?

0
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:WpfApplication1.Model"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <l:ViewModel />
    </Window.DataContext>
    <Window.Resources>
        <ControlTemplate x:Key="errorTemplate">
            <DockPanel LastChildFill="true">
                <Border Background="OrangeRed" DockPanel.Dock="Right" Margin="3,0,0,0" Width="20" Height="20" CornerRadius="5" ToolTip="{Binding ElementName=adoner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                    <TextBlock Text="!" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White" />
                </Border>
                <AdornedElementPlaceholder Name="adoner" VerticalAlignment="Center">
                    <Border BorderBrush="OrangeRed" BorderThickness="1" />
                </AdornedElementPlaceholder>
            </DockPanel>
        </ControlTemplate>
        <Style x:Key="textBoxError" TargetType="TextBox">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Label Content="Wiek:" HorizontalAlignment="Left"
               VerticalAlignment="Top" Margin="42,119,0,0"/>
        <Label Content="Nazwisko:" HorizontalAlignment="Left"
               VerticalAlignment="Top" Margin="18,76,0,0"/>
        <Label Content="Imię:" HorizontalAlignment="Left"
               VerticalAlignment="Top" Margin="46,33,0,0"/>
      
        <TextBox Height="23" HorizontalAlignment="Left" Margin="81,33,0,0"
         Name="tbFirstName" VerticalAlignment="Top" Width="155"
         Validation.ErrorTemplate="{StaticResource errorTemplate}"
         Style="{StaticResource textBoxError}"
         Text="{Binding FirstName, UpdateSourceTrigger=LostFocus,
         ValidatesOnDataErrors=True}" />

        <TextBox Height="23" HorizontalAlignment="Left" Margin="81,76,0,0"
         Name="tbLastName" VerticalAlignment="Top" Width="155"
         Validation.ErrorTemplate="{StaticResource errorTemplate}"
         Style="{StaticResource textBoxError}"
         Text="{Binding LastName, UpdateSourceTrigger=LostFocus,
         ValidatesOnExceptions=True}" />



        <TextBox Height="23" HorizontalAlignment="Left" Margin="81,119,0,0"
         Name="tbAge" VerticalAlignment="Top" Width="93"
         Validation.ErrorTemplate="{StaticResource errorTemplate}"
         Style="{StaticResource textBoxError}">
            <TextBox.Text>
                <Binding Path="Age" UpdateSourceTrigger="PropertyChanged" >
                    <Binding.ValidationRules>
                        <l:IntegerValidation ValidatesOnTargetUpdated="True"
                                     ValidationStep="RawProposedValue"
                                     MinValue="18"
                                     ErrorMessage="Osoba musi być pełnoletnia!" />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>

        <Button Content="Zapisz" Height="23" HorizontalAlignment="Left"
                Margin="105,188,0,0"
                Name="btSave" VerticalAlignment="Top" Width="75" />
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace WpfApplication1.Model
{
   
        public class ViewModel : INotifyPropertyChanged, IDataErrorInfo
        {
            public event PropertyChangedEventHandler PropertyChanged;

            virtual protected void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }

            private string firstName;
            private string lastName;
            private int age;

            public string FirstName
            {
                get { return firstName; }
                set
                {
                    firstName = value;
                    OnPropertyChanged("FirstName");
                }
            }

            public string Error
            {
                get { return String.Empty; }
            }

            public string this[string fieldName]
            {
                get
                {
                    string result = null;
                    if (fieldName == "FirstName")
                    {
                        if (string.IsNullOrEmpty(FirstName))
                            result = "Imię nie może być puste!";
                    }
                    return result;
                }
            }


            public string LastName
            { 
                get { return lastName; }

                set
                {
                    if (string.IsNullOrEmpty(value))
                        throw new ArgumentException("Nazwisko nie może być puste!");
                    lastName = value;
                    OnPropertyChanged("LastName");                
                }            
            } 

            public int Age
            {
                get { return age; }
                set
                {
                    age = value;
                    OnPropertyChanged("Age");
                }
            }
        }
}

Problem krótki, dla lastname nie ładuje błędu. Jak odpalam program to firstname i age jest w pomarańczowej ramce z wykrzyknikiem obok. Czyli ValidationRule i DataErrorValidationRule działają, nie działa ExceptionValidationRule.

pozdr

0

powyższy post jest mój

Update: błąd musi być w kodzie, testowałem to na VS2010 z Win Xp x32 to samo wyszło.

1

Teraz załapałem w czym problem. Używasz dwarodzaje walidacji: IDataErrorInfo lub poprzez rzucanie wyjątków. Jeżeli używasz tego drugiego to Visual Studio zawsze pokazuje gdzie został rzucony wyjątek. Dlatego lepiej implementować to pierwsze rozwiązanie. Jeżeli chcesz uruchomić program tak aby visual studio Ciebie nie zatrzymywało użyj opcji Startwithout debbuging (ctrl+f5)

0

no niestety nic to nie dało. Cały czas aby wyświetlić błąd muszę najpierw coś wpisać a potem skasować.
Nawet jak próbuję użyć samego kodu dla ExceptionValidationRule to po uruchomieniu aby pokazało błąd musi najpierw coś być wpisane a potem skasowane.

Update: przerobiłem kilka przykładów z tym typem walidacji, reakcja jest taka sama. Chyba musi tak być.

1

Exception jest rzucany tylko gdy prubujesz przypisać pustą wartość. Jeżeli inicjujesz obiekt to wartość nie jest ustawiana dla "LastName" tylko dla "lastName" więc exception nie ma jak się pojawić. Możesz utworzyuć pusty konstruktor dla ViewModel i przypisywać tam domyślne wartości dla First i LastName na przykład :

 
void ViewModel() 
{
LastName = string.Empty;
FirstName = string.Empty;
}

Czy teraz komunikat o błedzie sie pojawia ?

0

Taka sama reakcja. Czyli musi tak już być.

1

Posiedziałem na tym jeszcze chwilkę i nie wiem jak to zrobić zgodnie z MVVM.

Jednak jeżeli zmienisz
UpdateSourceTrigger=PropertyChanged
I przypiszesz w code behinde nad Loaded
tbLastName.Text = string.Empty;
to działka tak jak powinno,

0

zgadza się, teraz działa. Szkoda, że sama klasa ViewModel nie wystarczy, tak jak dla pozostałych metod.

1 użytkowników online, w tym zalogowanych: 0, gości: 1