Binding не имеет метода Clone, что является эффективным способом его копирования - PullRequest
10 голосов
/ 16 декабря 2009

Я хочу скопировать привязку, чтобы я мог установить для нее другое свойство источника, не затрагивая исходную привязку. Это просто случай, когда все свойства новой привязки совпадают со старой?

Ответы [ 3 ]

13 голосов
/ 20 февраля 2011

Вот мое решение проблемы:

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");
}
2 голосов
/ 16 декабря 2009

, если вы не можете найти способ сделать это, уже создайте расширение для 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(); 
}
0 голосов
/ 15 мая 2012

Я только что заметил в декомпилированном коде BindingBase, что у него есть внутренний метод Clone(), поэтому другое (небезопасное, не пытайтесь дома, использовать на свой страх и риск и т. Д.) Решение будет использовать отражение, чтобы обойти ограничения доступа компилятора:

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

Хотя не пробовал, поэтому может не сработать.

...