2009-12-16 71 views
9

我希望複製一個綁定,這是因爲我可以在其上設置不同的源屬性而不影響原始綁定。這只是將新綁定的所有屬性設置爲與舊相同的情況?綁定沒有克隆方法,什麼是複製它的有效方法

+1

我現在發現我不需要複製綁定,在代碼中,我可以在不同的元素上多次使用綁定。 – 2011-06-15 02:06:29

回答

2

如果你找不到一個方法來做到這一點,已經爲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

我想我只需要手動複製這些屬性然後... – 2010-01-13 00:43:55

13

這裏是我的問題的解決方案:

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

爲什麼ElementName和RelativeSource被註釋掉了?我猜你在克隆這些屬性時遇到了問題? – 2011-03-02 15:17:51

+2

綁定僅允許您設置ElementName,RelativeSource或Source之一。如果您嘗試設置多個,則會引發InvalidOperationException。 – 2011-04-04 14:25:17

+2

我在使用上述時遇到了問題,除了我將源代碼從舊的綁定複製到新的。在我的情況下,綁定繼承DataContext作爲其源。當我複製源時,它明確地將null設置爲顯然不會使用DataContext的源。要解決這個問題,請使用:'Source = binding.Source ?? DependencyProperty.UnsetValue; – xr280xr 2012-03-22 15:18:14

0

我只注意到在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 }); 
} 

沒有嘗試,雖然如此,它可能無法正常工作。

相關問題