Login Login
MORE

WIDGETS

Widgets

Wanted articles
Who is online?
Article tools

CSharp:WPF Soluzioni varie

From Aino Wiki

Jump to: navigation, search

Interfaccia

ViewModel

URL di esempi:

Aggiunta manuale per il Binding

Supponendo di voler aggiungere manualmente ad una vista un ViewModel, ci occorrerà definire una classe di ViewModel e associarlo al DataContext della vista via programma.

WPF Manual ViewModel assign.png

Il modello possiamo supporre provenga dall'App.Config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <appSettings>
        <add key="StartDirectory_SourcePath" value="D:\Documenti\FOX_New Zeland\Development" />
        <add key="EndDirectory_DestinationPath" value="D:\Backup\xxx" />
        <add key="DefaultFilePatternToSearch" value="APPOINTMENT.cs" />


        <add key="FoxClientLogPath_Debug" value="D:\Documenti\FOX_New Zeland\Development\FOX.Dashboard\bin\Debug\log\FoxDashboard.log" />
    </appSettings>
</configuration>

L'interfaccia alla nostra vista sarà il view model con la seguente Classe

namespace SimplyFileBackup.ViewModels
{
    using System.Configuration;
    using System.Windows.Input;
    public class MainViewModel : ViewModelBase
    {
        #region Properties

        public string AppCfg_StartDirectory_SourcePath
        {
            get
            {
                return ConfigurationManager.AppSettings["StartDirectory_SourcePath"];
            }
        }

        public string AppCfg_EndDirectory_DestinationPath
        {
            get
            {
                return ConfigurationManager.AppSettings["EndDirectory_DestinationPath"];
            }
        }

        public string AppCfg_DefaultFilePatternToSearch
        {
            get
            {
                return ConfigurationManager.AppSettings["DefaultFilePatternToSearch"];
            }
        }

        public static string AppCfg_FoxClientLogPath_Debug
        {
            get
            {
                return ConfigurationManager.AppSettings["FoxClientLogPath_Debug"];
            }
        }
        #endregion
    }
}

La classe Vista da cui eredita sarà:

using System.ComponentModel;

namespace SimplyFileBackup.ViewModels
{
    /// <summary>
    /// Provides common functionality for ViewModel classes
    /// </summary>
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
}

Nel code behind della vista nel suo costruttore basterà assegnargli il DataContext voluto

// Per il DataBinding
this.DataContext = new ViewModels.MainViewModel();

La vista sarà così composta nei punti salienti dello XAML:



<TextBox x:Name="TxtSourcePath" Grid.Column="1" Grid.Row="0" 
		 Text="{Binding Path=AppCfg_StartDirectory_SourcePath, Mode=OneWay}"
		 Width="Auto" Margin="10,15,0,0"
		 VerticalAlignment="Top" HorizontalAlignment="Stretch" 
		 IsEnabled="True"/>

Aggiunta statica per ogni vista

ToDo

Binding

Tra ComboBox dipendenti

Ci sono due comboBox in funzione della scelta fatta su quella di sinistra quella di destra si caricherà di conseguenza.
Contenuto della comboBox di sinistra:

WPF Binding Combo dipendenti.png

Caso 1, selezionando "Form", la combo di destra è così popolata:

WPF Binding Combo dipendenti 02.png

Caso 2, selezionando "Questionnaire", la combo di destra è così popolata:

WPF Binding Combo dipendenti 03.png

Esempio 1

La comboBox di sinistra ha il binding (ItemsSource nello XAML) mediante una Property che è una Lista di oggetti, la selezione (SelectedItem nello XAML) effettuata verrà riportata in un'altra property dedicata, allo stesso modo quella di destra. Nonappena viene fatta una selezione a sinistra la property con la selezione si riempie e verrà popolata la property del binding della comboBox di destra.
ATTENZIONE la property del binding della combo di destra è popolata assegnandovi un NUOVO oggetto e non è popolata direttamente! (questo è indipensabile per il binding dinamico pena il funzionamento al solo primo caricamento!)

XAML

La vista inizierà con le seguenti direttive:

<UserControl x:Class="Fox.Module.Customer.SubModule.FormsAndQuestionnaires"
...etc
             xmlns:FOX_Module_Questionnaires_ViewModel="clr-namespace:Fox.Module.Customer.ViewModel" 
...etc
             x:Name="UserControl">

E conterrà anche le seguenti due definizioni di ComboBox ComboBox di sinsitra:

<telerik:RadComboBox x:Name="cboQuestionnairType" Grid.Column="1" 
					 Margin="10,0,0,0" Width="200" 
					 HorizontalAlignment="Left" 
					 Style="{StaticResource cboStandard}" Cursor="Hand" 
					 ClearSelectionButtonVisibility="Visible" 
					 ItemsSource="{Binding QuestionnaireGroupTypes}" 
					 SelectedItem="{Binding SelectedQuestGroupType, Mode=TwoWay, UpdateSourceTrigger='PropertyChanged'}" 
					 DisplayMemberPath="Description" >
</telerik:RadComboBox>

ComboBox di destra:

<telerik:RadComboBox x:Name="cboDocumentType" Grid.Column="3" 
					 Margin="15,0,0,0" Width="200"
					 HorizontalAlignment="Left" 
					 Style="{StaticResource cboStandard}" Cursor="Hand"                                          
					 ClearSelectionButtonVisibility="Visible"
					 IsEnabled="{Binding Path=IsMandatoryDocumentType, Converter={StaticResource BooleanToVisibility}, ConverterParameter='1', UpdateSourceTrigger='PropertyChanged'}"
					 ItemsSource="{Binding QuestionnaireTypes}" 
					 SelectedItem="{Binding SelectedQuestType, Mode=TwoWay, UpdateSourceTrigger='PropertyChanged'}" 
					 DisplayMemberPath="Description" >
</telerik:RadComboBox>
Code beihnd

Nella Classe del ViewModel "QuestionnaireViewModel", a cui è associata la vista (XAML riportato nel paragrafo precedente), abbiamo il seguente codice ceh gestisce il Binding:

namespace Fox.Module.Customer.ViewModel
{
public class QuestionnaireViewModel : ViewModelBase
{

// ------------------------- ComboBox di Sinistra ----------------------
private List<QuestionnaireTemplateModel> _QuestionnaireGroupTypes;
public List<QuestionnaireTemplateModel> QuestionnaireGroupTypes
{
	get { return _QuestionnaireGroupTypes; }
	set
	{
		if (_QuestionnaireGroupTypes != value)
		{
			_QuestionnaireGroupTypes = value;
			OnPropertyChanged(() => this.QuestionnaireGroupTypes);
		}
	}
}

private QuestionnaireTemplateModel _SelectedQuestGroupType = null;
public QuestionnaireTemplateModel SelectedQuestGroupType
{
	get { return _SelectedQuestGroupType; }
	set
	{
		if (_SelectedQuestGroupType != value)
		{
			IsSave = true;
			SelectedQuestType = null;
			QuestionnaireTypes = null;
			switch (value.Code)
			{
				case "GPR":
				case "ARL":
					IsMandatoryDocumentType = false; // Used to show the * and to enable the control "cboDocumentType"                            
					break;
				case "FRM":
				case "QST":
					IsMandatoryDocumentType = true; // Used to show the * and to enable the control "cboDocumentType"
					QuestionnaireTemplateModel qtm = new QuestionnaireTemplateModel();
					List<QuestionnaireTemplateModel> __QuestionnaireTypes = new List<QuestionnaireTemplateModel>();
					foreach (CU_S_QUESTIONNAIRE_TEMPLATEDto q in m_Cache_LstQuestionnaireTemplate)
					{
						if (q.TEMPLATE_GROUP_CODE.Equals(value.Code))
						{
							qtm = new QuestionnaireTemplateModel()
							{
								Code = q.TEMPLATE_CODE,
								Description = q.TEMPLATE_DESCR
							};
							__QuestionnaireTypes.Add(qtm);
						}
					}
					QuestionnaireTypes = __QuestionnaireTypes;
					break;
				default:
					break;
			}
			_SelectedQuestGroupType = value;
			OnPropertyChanged(() => this.SelectedQuestGroupType);
		}
	}
}


// ------------------------- ComboBox di Destra ----------------------
private List<QuestionnaireTemplateModel> _QuestionnaireTypes;
public List<QuestionnaireTemplateModel> QuestionnaireTypes
{
	get { return _QuestionnaireTypes; }
	set
	{
		if (_QuestionnaireTypes != value)
		{
			_QuestionnaireTypes = value;
			OnPropertyChanged(() => this.QuestionnaireTypes);
		}
	}
}

private QuestionnaireTemplateModel _SelectedQuestType = null;
public QuestionnaireTemplateModel SelectedQuestType
{
	get { return _SelectedQuestType; }
	set
	{
		if (_SelectedQuestType != value)
		{
			_SelectedQuestType = value;
			VisibilityOfGrid();
			IsWorking = true;
			LoadAnswersQuestionnaires();
			IsWorking = false;
		}
	}
}

// etc
}
}

Esempio 2

La comboBox di sinistra ha il binding (ItemsSource nello XAML) mediante una Property che è una Lista di oggetti, la selezione (SelectedItem nello XAML) effettuata verrà riportata in un'altra property dedicata, allo stesso modo quella di destra. Nonappena viene fatta una selezione a sinistra la property con la selezione si riempie e verrà popolata la property del binding della comboBox di destra.

XAML

La vista inizierà con le seguenti direttive:

<UserControl x:Class="FOX.Module.NewCustomer.views.RegProfilo"
			 .. etc
             xmlns:local="clr-namespace:FOX.Module.NewCustomer.BindingObjects"
			 .. etc
             >

E conterrà anche le seguenti due definizioni di ComboBox ComboBox di sinsitra:

<telerik:RadComboBox  Grid.Row="1" Grid.Column="2" Style="{StaticResource cboStandard}" 
					  Cursor="Hand" Width="178"  HorizontalAlignment="Left"
					  ItemsSource="{Binding sourcelist}" 
					  IsEnabled="{Binding isInsertMode,Converter={StaticResource BooleanConverter}}" 
					  Margin="6,10,0,0" 
					  SelectedValuePath="ENTITY_CODE" 
					  TextSearch.TextPath="ENTITY_DESCR"
					  TextSearchMode="Contains" 
					  IsTextSearchEnabled="True"
					  CanAutocompleteSelectItems="True" 
					  IsReadOnly="False"
					  IsEditable="True"
					  IsFilteringEnabled="True">
	<telerik:RadComboBox.SelectedValue>
		<Binding Path="SOURCE_CODE" 
				UpdateSourceTrigger="PropertyChanged" 
				Mode="TwoWay">
			<Binding.ValidationRules>
				<CustomerValidators:RequiredCustomerValidator 
						Controlname="{l:LocalizeByModule DefaultValue='Source', Key=txbsourcelist}">
					<CustomerValidators:RequiredCustomerValidator.CustomerType>
						<CustomerValidators:CustomerType 
							DataContext="{Binding Source={StaticResource DataContextBridge}, Path=DataContext}" 
							CustomerTypeCode="{Binding isSourceRequired}" />
					</CustomerValidators:RequiredCustomerValidator.CustomerType>
					<CustomerValidators:RequiredCustomerValidator.ValidationParam>
						<CustomerValidators:Param 
							DataContext="{Binding Source={StaticResource DataContextBridge}, Path=DataContext}" 
							Key="SOURCE_CODE" 
							Value="{Binding SOURCE_CODE}" />
					</CustomerValidators:RequiredCustomerValidator.ValidationParam>
				</CustomerValidators:RequiredCustomerValidator>
			</Binding.ValidationRules>
		</Binding>
	</telerik:RadComboBox.SelectedValue>
	<telerik:RadComboBox.ItemTemplate>
		<DataTemplate>
			<TextBlock>
				<TextBlock.Text>

					<Binding Path="ENTITY_DESCR" />

				</TextBlock.Text>
			</TextBlock>
		</DataTemplate>
	</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>

ComboBox di destra:

<telerik:RadComboBox  Grid.Row="1" Grid.Column="6" 
					  IsEnabled="{Binding isInsertMode,Converter={StaticResource BooleanConverter}}" 
					  Style="{StaticResource cboStandard}" 
					  Cursor="Hand" 
					  Margin="5,10,0,0"  
					  ItemsSource="{Binding subsourcelist}" 
					  SelectedValuePath="ENTITY_CODE" 
					  Width="178"  HorizontalAlignment="Left"
					  TextSearch.TextPath="ENTITY_DESCR"
					  TextSearchMode="Contains" 
					  IsTextSearchEnabled="True"
					  CanAutocompleteSelectItems="True" 
					  IsReadOnly="False"
					  IsEditable="True"
					  IsFilteringEnabled="True">
	<telerik:RadComboBox.SelectedValue>
		<Binding Path="SUB_SOURCE_CODE" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
			<Binding.ValidationRules>
				<CustomerValidators:RequiredCustomerValidator Controlname="{l:LocalizeByModule DefaultValue='SubSource', Key=txbsubsourcelist}">
					<CustomerValidators:RequiredCustomerValidator.CustomerType>
						<CustomerValidators:CustomerType 
							DataContext="{Binding Source={StaticResource DataContextBridge}, Path=DataContext}" 
							CustomerTypeCode="{Binding isSubSourceRequired}" />
					</CustomerValidators:RequiredCustomerValidator.CustomerType>
					<CustomerValidators:RequiredCustomerValidator.ValidationParam>
						<CustomerValidators:Param 
							DataContext="{Binding Source={StaticResource DataContextBridge}, Path=DataContext}" 
							Key="SUB_SOURCE_CODE" 
							Value="{Binding SUB_SOURCE_CODE}" />
					</CustomerValidators:RequiredCustomerValidator.ValidationParam>
				</CustomerValidators:RequiredCustomerValidator>
			</Binding.ValidationRules>
		</Binding>
	</telerik:RadComboBox.SelectedValue>
	<telerik:RadComboBox.ItemTemplate>
		<DataTemplate>
			<TextBlock>
				<TextBlock.Text>

					<Binding Path="ENTITY_DESCR" />

				</TextBlock.Text>
			</TextBlock>
		</DataTemplate>
	</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>
Code beihnd

Nella Classe del ViewModel "QuestionnaireViewModel", a cui è associata la vista (XAML riportato nel paragrafo precedente), abbiamo il seguente codice ceh gestisce il Binding:

namespace FOX.Module.NewCustomer.BindingObjects
{
    public class WizardBinding : INotifyPropertyChanged, ICloneable
    {
 
		// ------------------ Prima ComboBox ------------------
        private List<CM_S_REFERRAL_HIERARCHY_EXT_NZLDto> _sourcelist;
        public List<CM_S_REFERRAL_HIERARCHY_EXT_NZLDto> sourcelist
        {
            get
            {
                _sourcelist = ReferralHierachyCache.GetList(UserLogin.User.CurrentUser, false).
                    Where(x => x.COMPANY_CODE == UserLogin.User.CurrentUser.COMPANY_CODE
                    && x.DIVISION_CODE == UserLogin.User.CurrentUser.DIVISION_CODE
                    && x.ENTITY_TYPE == "SOU").ToList();
                return _sourcelist;
 
            }
        }
 
		private string _SOURCE_CODE;
        public string SOURCE_CODE
        {
            get
            {
                return _SOURCE_CODE;
            }
            set
            {
                if (_SOURCE_CODE != value)
                {
                    _SOURCE_CODE = value;
                    OnPropertyChanged("SOURCE_CODE");
                    OnPropertyChanged("subsourcelist");
                    SUB_SOURCE_CODE = null;
                    OnPropertyChanged("referrallist");
                    REFERRAL_CODE = null;
                    MEDIATYPE_CODE = null;
                    MEDIATYPE_DESCRIZ = null;
                    OnPropertyChanged("MEDIATYPE_DESCRIZ");
 
                }
            }
        }
 
		// ------------------ Seconda ComboBox ------------------
        private string _SUB_SOURCE_CODE;
        public string SUB_SOURCE_CODE
        {
            get
            {
                return _SUB_SOURCE_CODE;
            }
            set
            {
                if (_SUB_SOURCE_CODE != value)
                {
                    _SUB_SOURCE_CODE = value;
                    OnPropertyChanged("SUB_SOURCE_CODE");
 
                   // referrallist.Clear();
                    OnPropertyChanged("referrallist");
 
                    if (isInsertMode)
                    {
                        if (_SUB_SOURCE_CODE!=null)
                            MEDIATYPE_CODE = subsourcelist.Where(X => X.ENTITY_CODE == _SUB_SOURCE_CODE).FirstOrDefault().MEDIATYPE_CODE;
 
                        OnPropertyChanged("MEDIATYPE_DESCRIZ");
                    }
                }
            }
        }
 
        private List<CM_S_REFERRAL_HIERARCHY_EXT_NZLDto> _subsourcelist;
        public List<CM_S_REFERRAL_HIERARCHY_EXT_NZLDto> subsourcelist
        {
            get
            {
                _subsourcelist = ReferralHierachyCache.GetList(UserLogin.User.CurrentUser, false).
                    Where(x => x.COMPANY_CODE == UserLogin.User.CurrentUser.COMPANY_CODE
                    && x.DIVISION_CODE == UserLogin.User.CurrentUser.DIVISION_CODE
                    && x.ENTITY_TYPE == "SUB" && x.FATHER_CODE == SOURCE_CODE
                    && x.FATHER_TYPE == "SOU").ToList();
                return _subsourcelist;
 
            }
        }
 
	}
}

UserControl

Validators

Campo obbligatorio

Esempio 1

Caso del semplice validatore di campo mandatorio\obbligatorio.
Porzione dello XAML associato ad un controllo da validare:

<UserControl x:Class="NomeModulo_XAML"
             ...                     
             xmlns:CustomValidators="clr-namespace:Fox.Module.Customer.Validations"
             ...>

                    <TextBlock Name="lblMandatoryQuestionnaireType" Grid.Column="0" 
                               Text="*" VerticalAlignment="Bottom" Margin="70,0,3,2"
                               ToolTip="{l:LocalizeByModule DefaultValue='Mandatory field', Key='lblMandatoryQuestionnaireType'}" />
                    <telerik:RadComboBox x:Name="cboQuestionnairType" Grid.Column="1" 
                                         Margin="10,0,0,0" Width="200" 
                                         HorizontalAlignment="Left" 
                                         Style="{StaticResource cboStandard}" Cursor="Hand" 
                                         ClearSelectionButtonVisibility="Visible" 
                                         ItemsSource="{Binding QuestionnaireGroupTypes}" 
                                         DisplayMemberPath="Description" >
                        <telerik:RadComboBox.SelectedItem>
                            <Binding Path="SelectedQuestGroupType" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
                                <Binding.ValidationRules>
                                    <CustomValidators:RequiredValidator
                                            ControlName="{l:LocalizeByModule DefaultValue='Source', Key=cboQuestionnairType}">
                                    </CustomValidators:RequiredValidator>                                    
                                </Binding.ValidationRules>
                            </Binding>
                        </telerik:RadComboBox.SelectedItem>

                    </telerik:RadComboBox>
Il codice code behind rispecchia la seguente struttura:
WPF CustomValidator es1.png

La classe del validatore dovrà ereditare dalla classe "ValidationRule"

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Controls;

namespace Fox.Module.Customer.Validations
{
    public class RequiredValidator : ValidationRule
    {
        #region Properties
        /// <summary>
        /// Control name to validate
        /// </summary>
        public string ControlName { get; set; }

        
        private List<Param> _inputParamsListToCheck = new List<Param>();
        public List<Param> InputParamsListToCheck
        {
            get { return _inputParamsListToCheck; }
            set { _inputParamsListToCheck = value; }
        }

        private Param _inputVvalidationRule;
        public Param InputValidationRule
        {
            get { return _inputVvalidationRule; }
            set { _inputVvalidationRule = value; }
        }
        #endregion

        public override System.Windows.Controls.ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            bool isValid = true;
            
            if (InputValidationRule != null)
            {
                isValid = CheckRule(InputValidationRule.Key, value);
            }
            else
            {
                if (value == null || string.IsNullOrWhiteSpace(value.ToString()) || value.ToString() == "False")
                {
                    isValid = false;
                }
                else
                {
                    isValid = true;
                }
            }
            
            if (isValid == false)
            {
                string message1 = FOX.Localization.LocalizationManager.GetProvider(GetType().FullName).GetString("RequiredValue", "is a mandatory field");
                //string message2 = FOX.Localization.LocalizationManager.GetProvider(GetType().FullName).GetString("RequiredValue2", "is mandatory");
                return new System.Windows.Controls.ValidationResult(false, string.Format("'{0}' '{1}'.", message1, ControlName));
            }
            return new System.Windows.Controls.ValidationResult(true, null);
        }

        #region Custom private methods
        private bool CheckRule(string rule, object value)
        {
            switch (rule)
            {
                case "ONE_OPTION_IS_CHECKED":
                    return FindParamValue(InputParamsListToCheck, true);

                case "ONE_CHECKBOX_IS_CHECKED":
                    return FindParamValue(InputParamsListToCheck);

                case "VALIDATE_IF_NOT_CHECKED":
                    return ChekParamValue(InputParamsListToCheck, "FLAG_TO_CHECK", "False,N", value);

                case "VALIDATE_IF_CHECKED":
                    return ChekParamValue(InputParamsListToCheck, "FLAG_TO_CHECK", "True,Y", value);                    
            }
            return true;
        }

        private bool FindParam(List<Param> myList, string valueToFind)
        {
            Param result = myList.Find(

                delegate (Param myObj)
                {
                    return (myObj.Key == valueToFind);
                }
            );

            if (result != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private bool FindParamValue(List<Param> myList)
        {
            Param result = myList.Find(delegate (Param myObj)   {
                                                                    return (!String.IsNullOrEmpty(myObj.Value));
                                                                }
            );

            if (result != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        private bool FindParamValue(List<Param> myList, object valueToFind)
        {
            Param result = myList.Find(

                delegate (Param myObj)
                {
                    return (myObj.Value == valueToFind.ToString() || myObj.Value != null);

                }
            );
            if (result != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private bool ChekParamValue(List<Param> myList, string Key, object valueToFind, object value)
        {
            Param result = myList.Find(

                delegate (Param myObj)
                {
                    if (myObj.Value == null)
                        return false;
                    return (myObj.Key == Key && valueToFind.ToString().Contains(myObj.Value));
                }
            );

            if (result != null)
            {
                if (value == null || string.IsNullOrEmpty((string)value))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return true;
            }
        }        
        #endregion
    }
}

Pre finire l'esempio segue la classe usata per passare i parametri:

using System.Windows;

namespace Fox.Module.Customer.Validations
{
    public class Param : FrameworkElement
    {
        public static readonly DependencyProperty ParamPropFieldKey =
        DependencyProperty.Register("Key", typeof(string), typeof(Param), new UIPropertyMetadata(string.Empty));
        
        public string Key
        {
            get { return (string)GetValue(ParamPropFieldKey); }
            set { SetValue(ParamPropFieldKey, value); }
        }

        public static readonly DependencyProperty ParamPropValue =
        DependencyProperty.Register("Value", typeof(string), typeof(Param), new UIPropertyMetadata(string.Empty));
        
        public string Value
        {
            get { return (string)GetValue(ParamPropValue); }
            set { SetValue(ParamPropValue, value); }
        }
    }
}

Regular Expression

Il seguente validatore verifica che si sia inserito un numero decimale con tre cifre nella parte intera e al più due cifre decimali.
XAML della vista:

<TextBox Name="txbLeftdBDb"                                         
		 FontWeight="Bold" Margin="5,0" Width="50" IsEnabled="{Binding IsClinicalEditable}"
		 Style="{StaticResource txtStandard}" MaxLength="6" Height="23" VerticalAlignment="Top">
	<TextBox.Text>
		<Binding Path="ClaimInfo.PTA1_L" StringFormat="N2" NotifyOnSourceUpdated="True" Mode="TwoWay">
			<Binding.ValidationRules>

				<CustomValidators:RegExValidator 
						ControlName="txbLeftdBDb" 
						RegExPattern="^\d{0,3}(\.\d{0,2})?$" 
						ErrorMessage="{l:LocalizeByModule DefaultValue='Value not allowed', Key=ErrValueNotallowd}">
				</CustomValidators:RegExValidator>

			</Binding.ValidationRules>
		</Binding>
	</TextBox.Text>
</TextBox>

Validatore dal code Behind:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Controls;
 
namespace FOX.Module.ClaimsInformation.Apac.Validations
{
    public class RegExValidator : ValidationRule
    {
        #region Properties
        public string ControlName { get; set; }
        public string RegExPattern { get; set; }
        public string ErrorMessage { get; set; }
        #endregion
 
        public override System.Windows.Controls.ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            Regex regEx = new Regex(RegExPattern);
 
            if (String.IsNullOrWhiteSpace(ErrorMessage))
            {
                ErrorMessage = string.Format("Value not allowed");
            }
            if (regEx.IsMatch((string)value))
            {
                return ValidationResult.ValidResult;
            }
            else
            {
                return new ValidationResult(false, ErrorMessage);
            }
        }
    }
}

Mappa e Link


C# | WPF | WPF Tips


Visual Studio


Parole chiave:

Author