Je souhaite copier une contraignante, cela est donc afin que je puisse définir une propriété source différente dessus sans affecter la liaison d'origine. Est-ce juste un cas de définition de toutes les propriétés de la nouvelle liaison à être identique à celle des anciens? P>
4 Réponses :
Si vous ne trouvez pas une méthode pour le faire, créez déjà une extension pour la liaison.
public static class BindingExtensions { public static Binding Clone(this Binding binding) { var cloned = new Binding(); //copy properties here return cloned; } } public void doWork() { Binding b= new Binding(); Binding nb = b.Clone(); }
Voici ma solution au problème:
public static BindingBase CloneBinding(BindingBase bindingBase, object source) { var binding = bindingBase as Binding; if (binding != null) { var result = new Binding { Source = source, AsyncState = binding.AsyncState, BindingGroupName = binding.BindingGroupName, BindsDirectlyToSource = binding.BindsDirectlyToSource, Converter = binding.Converter, ConverterCulture = binding.ConverterCulture, ConverterParameter = binding.ConverterParameter, //ElementName = binding.ElementName, FallbackValue = binding.FallbackValue, IsAsync = binding.IsAsync, Mode = binding.Mode, NotifyOnSourceUpdated = binding.NotifyOnSourceUpdated, NotifyOnTargetUpdated = binding.NotifyOnTargetUpdated, NotifyOnValidationError = binding.NotifyOnValidationError, Path = binding.Path, //RelativeSource = binding.RelativeSource, StringFormat = binding.StringFormat, TargetNullValue = binding.TargetNullValue, UpdateSourceExceptionFilter = binding.UpdateSourceExceptionFilter, UpdateSourceTrigger = binding.UpdateSourceTrigger, ValidatesOnDataErrors = binding.ValidatesOnDataErrors, ValidatesOnExceptions = binding.ValidatesOnExceptions, XPath = binding.XPath, }; foreach (var validationRule in binding.ValidationRules) { result.ValidationRules.Add(validationRule); } return result; } var multiBinding = bindingBase as MultiBinding; if (multiBinding != null) { var result = new MultiBinding { BindingGroupName = multiBinding.BindingGroupName, Converter = multiBinding.Converter, ConverterCulture = multiBinding.ConverterCulture, ConverterParameter = multiBinding.ConverterParameter, FallbackValue = multiBinding.FallbackValue, Mode = multiBinding.Mode, NotifyOnSourceUpdated = multiBinding.NotifyOnSourceUpdated, NotifyOnTargetUpdated = multiBinding.NotifyOnTargetUpdated, NotifyOnValidationError = multiBinding.NotifyOnValidationError, StringFormat = multiBinding.StringFormat, TargetNullValue = multiBinding.TargetNullValue, UpdateSourceExceptionFilter = multiBinding.UpdateSourceExceptionFilter, UpdateSourceTrigger = multiBinding.UpdateSourceTrigger, ValidatesOnDataErrors = multiBinding.ValidatesOnDataErrors, ValidatesOnExceptions = multiBinding.ValidatesOnDataErrors, }; foreach (var validationRule in multiBinding.ValidationRules) { result.ValidationRules.Add(validationRule); } foreach (var childBinding in multiBinding.Bindings) { result.Bindings.Add(CloneBinding(childBinding, source)); } return result; } var priorityBinding = bindingBase as PriorityBinding; if (priorityBinding != null) { var result = new PriorityBinding { BindingGroupName = priorityBinding.BindingGroupName, FallbackValue = priorityBinding.FallbackValue, StringFormat = priorityBinding.StringFormat, TargetNullValue = priorityBinding.TargetNullValue, }; foreach (var childBinding in priorityBinding.Bindings) { result.Bindings.Add(CloneBinding(childBinding, source)); } return result; } throw new NotSupportedException("Failed to clone binding"); }
Pourquoi ElementName et RelativeSource ont-ils commenté? Je suppose que vous avez rencontré un problème lorsque vous essayez de cloner ces propriétés?
La liaison vous permet seulement de définir l'un des noms, RelateSource ou Source. Si vous essayez de définir plus d'un, cela jette une introduction invalide.
J'avais du mal à utiliser ce qui précède, sauf que je copie la source de la vieille liaison au nouveau. Dans mon cas, la liaison hérite du DataContext comme source. Lorsque je copie la source, il définit explicitement NULL comme source qui provoque apparemment que le DataContext ne doit pas utiliser. Pour surmonter cela, utilisez: 'Source = Binding.Source ?? DépendanceProperty.unsetValue;
Merci, tu m'as sauvé une heure!
Je viens de remarquer le code décompilé de liaison à la liaison qu'il a une méthode interne clone () code>, donc une autre (dangereuse, n'essayez pas à la maison, utilisez-la à votre propre risque, etc.). Soyez d'utiliser la réflexion pour contourner les limitations d'accès du compilateur:
public static BindingBase CloneBinding(BindingBase bindingBase, BindingMode mode = BindingMode.Default)
{
var cloneMethodInfo = typeof(BindingBase).GetMethod("Clone", BindingFlags.Instance | BindingFlags.NonPublic);
return (BindingBase) cloneMethodInfo.Invoke(bindingBase, new object[] { mode });
}
Je viens de commencer à utiliser ceci. Ce n'est pas le plus efficace mais c'est assez rapide pour moi jusqu'à présent. C'est simple et en théorie ne devrait manquer aucune propriété. Inspiré par une autre question Réponse a>. p> p>
J'ai maintenant constaté que je n'ai pas besoin de copier une contraignante, en code, je peux utiliser une liaison plus d'une fois sur différents éléments.