我希望复制一个绑定,这样我就可以在其上设置不同的源属性而不会影响原始绑定。这只是将新绑定的所有属性设置为与旧的相同的情况吗?
答案 0 :(得分: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");
}
答案 1 :(得分: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();
}
答案 2 :(得分: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 });
}
但是没试过,所以它可能不起作用。
答案 3 :(得分:0)
我刚刚开始使用它。到目前为止,它并不是最有效的,但足够快。它很简单,理论上也不应错过任何特性。
using System.IO;
using System.Windows.Data;
using System.Windows.Markup;
using System.Xml;
static Binding CloneBinding(Binding binding)
{
var xaml = XamlWriter.Save(binding);
var stringReader = new StringReader(xaml);
var xmlReader = XmlReader.Create(stringReader);
return (Binding)XamlReader.Load(xmlReader);
}
受到另一个问题的answer的启发。