views:

324

answers:

0

Hello Experts !!

I've built a wpf windows application in with there is a registration form.

Using IDataErrorInfo i could successfully bind the field to a class property and with the help of styles display meaningful information about the error to users.About the submit button i use the MultiDataTrigger with conditions (Based on a post here on stackoverflow).All went well.

Now i need to do the same for the passwordbox and apparently it's not as straight forward.I found on wpftutorial an article and gave it a try but for some reason it wasn't working. i've tried another one from functionalfun.

And in this Functionalfun case the properties(databind,databound) are not recognized as dependencyproperty even after i've changed their name as suggested somewhere in the comments plus i don't have an idea whether it will work for a windows application, since it's designed for web.

what i did with the functionalfun approach is that i've created the PasswordBoxAssistant class in the project under folder custom_objects.So i has the namespace: Myproject.custom_objects.below are how i used it in the project.I have BindPassword property and BoundPassword both underlined (Dependency Property field missing)

<Window x:Class="Myproject.Recharge"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:data="clr-namespace:Myproject"
    xmlns:ff="clr-namespace:Myproject.custom_objects"
Title="Myprojecttitle">
<Window.Resources>
    <data:General x:Key="recharge" />
    <Style x:Key="validButton" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}" >
        <Setter Property="IsEnabled" Value="False"/>
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding ElementName=txtRecharge, Path=(Validation.HasError)}" Value="false" />
                     <Condition Binding="{Binding ElementName=txtPassword, Path=(Validation.HasError)}" Value="false" />
                </MultiDataTrigger.Conditions>
                <Setter Property="IsEnabled" Value="True" />
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>

    <Style x:Key="passboxerrors" TargetType="{x:Type PasswordBox}" BasedOn="{StaticResource {x:Type PasswordBox}}">
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <DockPanel>
                            <TextBlock DockPanel.Dock="Bottom" Foreground="Red" FontSize="9" Text="{Binding ElementName=errordisplay,Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
                            <Border BorderBrush="Red" BorderThickness="2">
                                <AdornedElementPlaceholder Name="errordisplay"/>
                            </Border>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>


    <Style x:Key="txtboxerrors" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                <Setter Property="Validation.ErrorTemplate">
                    <Setter.Value>
                        <ControlTemplate>
                            <DockPanel LastChildFill="True">
                                <TextBlock DockPanel.Dock="Bottom" FontSize="8" FontWeight="ExtraBold" Foreground="red" Padding="5 0 0 0" Text="{Binding ElementName=showerror, 
                                    Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"></TextBlock>

                                <Border BorderBrush="Red" BorderThickness="2">
                                    <AdornedElementPlaceholder Name="showerror" />
                                </Border>
                            </DockPanel>

                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<TextBox Margin="12,69,12,70" Name="txtRecharge" Style="{StaticResource txtboxerrors}">
        <TextBox.Text>
            <Binding Path="Field" Source="{StaticResource recharge}" ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <ExceptionValidationRule />
                </Binding.ValidationRules>
            </Binding>
         </TextBox.Text>
    </TextBox>
    <PasswordBox ff:PasswordBoxAssistant.BindPassword="true" Margin="19,0,23,133" Name="txtPassword" TabIndex="2" KeyDown="txtPassword_KeyDown" ToolTip="enter your OR Communicator password" Height="23" VerticalAlignment="Bottom" Style="{StaticResource passboxerrors}">
            <ff:PasswordBoxAssistant.BoundPassword>
                <Binding Path="Password" Source="{StaticResource recharge}" ValidatesOnDataErrors="True" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <ExceptionValidationRule />
                    </Binding.ValidationRules>
                </Binding>
            </ff:PasswordBoxAssistant.BoundPassword>
        </PasswordBox>
    <Button Height="23" Margin="98,0,0,12" Name="btnRecharge" VerticalAlignment="Bottom" Click="btnRecharge_Click" HorizontalAlignment="Left" Width="75" Style="{StaticResource validButton}">Recharge</Button></windows>

some C# :

 class General : IDataErrorInfo
{
    private string _field;
    private string _password;
    public string this[string columnName]
    {
        get 
        {
            string result = null;
            if(columnName == "Field")
            {
                if(Util.NullOrEmtpyCheck(this._field))
                {
                    result = "Field cannot be Empty";
                }
            }
            if(columnName == Password)
            {
                if (string.IsNullOrEmpty(Password))
                {
                    result = "Password Cannot be Empty";
                }
            }

            return result;
        }
    }

    public string Error
    {
        get { return null; }
    }

    public string Field
    {
        get { return _field; }
        set { _field = value; }
    }

    public string Password
    {
        get { return _password; }
        set { _password = value; }
    }
}

So what are suggestion you guys have for me? I mean how would you go about this? how do you do this since the databinding first purpose here is not to load data onto the fields they are just (for now) for data validation.

thanks for reading this.