QUAND L’UTILISERGénéralement, la classe Binding est la meilleure façon d’assigner une valeur à une propriété qui est dépendante d’un context. Pour des opérations plus complexe on utiliser les Converter avec le Binding. Si on a besoin d’encore plus de liberté on a accès la clases MarkupExtension.
UTILISATION SIMPLELorsqu’on fait une classe qui dérive de MarkupExtension, on doit implémenter la méthode ProvideValue. Dans ProvideValue, un IServiceProvider est passé qui fourni le DependencyObject et la DependencyProperty sur laquelle a été assigné le MarkupExtention. Ce qui en gros permet d’avoir un contrôle total sur l’objet. Voici un exemple simple d’utilisation des MarkupExtension :
XAML
CODE
public class MyExt : MarkupExtension{public string ExVal { get; set; }public override object ProvideValue(IServiceProvider serviceProvider){return ExVal;}}
UTILISATION CONCRETEDans cet exemple, le but est de sécuriser l’édition d’un champ à l’aide de la propriété IsEnabled. Les informations de sécurité proviennent de la base de données. La sécurité dépend également de l’état du formulaire; par exemple, on veut qu’on utilisateur puisse entrer de l’information si le formulaire est en mode « nouveau » et restreindre l’accès lorsqu’il est en mode « Édition. » De plus, l’information n’est pas présente dans le « ViewModel »
XAML
CODE: MarkupExtension
public class SecurityMarkupExtension : MarkupExtension{public SecurityMarkupExtension(){InitializeProperties();}public SecutityStateEnum SecuriyState { get; set; }public string SecurityCodeSearch { get; set; }public string SecurityCodeEdit { get; set; }public string SecurityCodeEditNew { get; set; }private void InitializeProperties(){SecuriyState = SecutityStateEnum.None;}public override object ProvideValue(IServiceProvider serviceProvider){IProvideValueTarget valueProvider = (IProvideValueTarget)serviceProvider;Binding bind = new Binding();bind.ConverterParameter = this;bind.Converter = SecurityBindingConverter.Instance;bind.Source = ApplicationStatusHandler.Instance;bind.Path = new System.Windows.PropertyPath(« ApplicationState »);bind.Mode = BindingMode.TwoWay;if (valueProvider.TargetObject is DependencyObject && valueProvider.TargetProperty is DependencyProperty){if (!DesignerProperties.GetIsInDesignMode((DependencyObject)valueProvider.TargetObject)){BindingOperations.SetBinding((DependencyObject)valueProvider.TargetObject, (DependencyProperty)valueProvider.TargetProperty, bind);return valueProvider.TargetObject.GetType().GetProperty(
valueProvider.TargetProperty.ToString()
).GetValue(valueProvider.TargetObject, null);}return false;}else{return ((DependencyProperty)valueProvider.TargetProperty).DefaultMetadata.DefaultValue;}}CODE: Converter
public class SecurityBindingConverter : IValueConverter{private static SecurityBindingConverter _instance;private static readonly object _padlock = new object();public static SecurityBindingConverter Instance{get{lock (_padlock){if (_instance == null){_instance = new SecurityBindingConverter();}return _instance;}}}public object Convert(object value, Type targetType, object parameter, CultureInfo culture){if (parameter is SecurityMarkupExtension){bool returnValue = false;SecurityMarkupExtension param = ((SecurityMarkupExtension)parameter);switch ((ApplicationStateEnum)value){case ApplicationStateEnum.Search:if ((param.SecuriyState & SecutityStateEnum.Searchable) == SecutityStateEnum.Searchable){returnValue = SecurityHandler.IsUserAllowed(param.SecurityCodeSearch);}else{returnValue = false;}break;case ApplicationStateEnum.Edition:if ((param.SecuriyState & SecutityStateEnum.Editable) == SecutityStateEnum.Editable){returnValue = SecurityHandler.IsUserAllowed(param.SecurityCodeEdit);}else{returnValue = false;}break;case ApplicationStateEnum.Creation:if ((param.SecuriyState & SecutityStateEnum.CanEditNew) == SecutityStateEnum.CanEditNew){returnValue = SecurityHandler.IsUserAllowed(param.SecurityCodeEditNew);}else{returnValue = false;}break;}return returnValue;}else{throw new Exception(« SecurityBindingConverter a besoin d’un paramètre de type SecurityBinding »);}}
Est-ce que le MultiBinding pourrait aussi fonctionner au lieu des MarkupExtensions ?
La classe [b]MultiBinding [/b]est situé, en termes de liberté, entre le [b]MarkupExtension [/b]et le [b]Binding[/b]. La grande différence c’est qu’une multitude de propriétés "Custom" peuvent être spécifiées dans un [b]MarkupExtension[/b]. Dans le cas présenté ici, le [b]MultiBinding [/b]ne pouvait pas faire l’affaire car on voulait que les définitions de sécurité soient spécifiées via l’interface. Comme dans l’exemple ci-haut: SecurityCodeSearch="Code4302".