2009-12-16 30 views
9

Tôi muốn sao chép một ràng buộc, điều này là để tôi có thể đặt thuộc tính nguồn khác trên đó mà không ảnh hưởng đến ràng buộc ban đầu. Đây có phải chỉ là một trường hợp thiết lập tất cả các thuộc tính trên ràng buộc mới giống như cũ không?Ràng buộc không có phương pháp Clone, cách hiệu quả để sao chép nó

+1

Tôi đã thấy rằng tôi không cần phải sao chép một ràng buộc, trong mã tôi có thể sử dụng một ràng buộc nhiều hơn một lần trên các yếu tố khác nhau. –

Trả lời

2

nếu bạn không thể tìm thấy phương pháp để thực hiện việc này, hãy tạo một exetension cho 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

tôi đoán tôi chỉ cần sao chép các thuộc tính đó theo cách thủ công rồi ... –

13

Đây là giải pháp của tôi cho vấn đề:

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

Tại sao ElementName và RelativeSource lại nhận xét? Tôi đoán bạn gặp phải một vấn đề khi cố gắng sao chép các thuộc tính đó? –

+2

Việc liên kết chỉ cho phép bạn đặt một trong các ElementName, RelativeSource hoặc Source. Nếu bạn cố gắng đặt nhiều hơn một, nó sẽ ném một InvalidOperationException. –

+2

Tôi gặp sự cố khi sử dụng ở trên, ngoại trừ tôi đã sao chép nguồn từ liên kết cũ sang mới. Trong trường hợp của tôi, ràng buộc kế thừa DataContext là nguồn của nó. Khi tôi sao chép nguồn, nó rõ ràng đặt null là nguồn mà dường như làm cho DataContext không được sử dụng. Để khắc phục điều này, hãy sử dụng: 'Source = binding.Source ?? DependencyProperty.UnsetValue; – xr280xr

0

Tôi chỉ nhận thấy trong BindingBase decompiled mã mà nó có một phương pháp nội Clone(), vì vậy khác (không an toàn, không nên cố gắng ở nhà, sử dụng nguy cơ của riêng bạn, vv) giải pháp sẽ được sử dụng phản ánh để vượt qua giới hạn truy cập của trình biên dịch:

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

Không thử, mặc dù vậy, nó có thể không hoạt động.

Các vấn đề liên quan