Binding does not have a Clone method, whats an effective way to copy it

久未见 提交于 2019-12-18 05:51:11

问题


I wish to copy a binding, this is so i can set a different source property on it without affecting the original binding. Is this just a case of setting all of the properties on the new binding to be the same as the old?


回答1:


if you can't find a method to do this already create an exetension for Binding.

    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(); 
}



回答2:


Here is my solution to the problem:

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");
}



回答3:


I just noticed in BindingBase decompiled code that it has an internal Clone() method, so another (unsafe, don't try at home, use at your own risk, etc.) solution would be to use reflection to bypass the compiler's access limitations:

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 });
}

Didn't try it, though, so it might not work.



来源:https://stackoverflow.com/questions/1911532/binding-does-not-have-a-clone-method-whats-an-effective-way-to-copy-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!