我正在尝试在NumericUpDown的value属性和cs对象的属性之间建立数据绑定。 NumericUpDown位于“模态”对话框中,因此我只希望在用户按下“确定”按钮时更新数据绑定。这个NumericUpDown在一个PropertyGrid中,在非Modal对话框的情况下工作正常,所以我不想修改最初创建数据绑定的XAML。我也不想仅仅为了更改数据绑定而复制XAML。所以,我试图在Modal对话框的Loaded事件处理程序中复制和修改数据绑定。
这里我复制并修改最初在XAML中创建的数据绑定。
void OnLoad(object sender, RoutedEventArgs e)
{
GetBindings(DialogPropPanel);
}
private void GetBindings(FrameworkElement root)
{
FieldInfo[] infos = root.GetType().GetFields(BindingFlags.Public | BindingFlags.FlattenHierarchy |
BindingFlags.Instance | BindingFlags.Static);
foreach(FieldInfo field in infos)
{
if(field.FieldType == typeof(DependencyProperty))
{
DependencyProperty dp = (DependencyProperty)field.GetValue(null);
BindingExpression ex = root.GetBindingExpression(dp);
if(ex != null)
{
PropertyElement elem = FindBoundElement(ex.DataItem, GroupContainer.PropertyGroups);
if(elem != null)
{
Binding bd = ex.ParentBinding;
if(bd.Mode == BindingMode.Default || bd.Mode == BindingMode.TwoWay)
{
// Copy the binding an change mode.
Binding newBinding = CreateOneTimeBinding(bd, ex.DataItem);
BindingOperations.ClearBinding(root, dp);
BindingOperations.SetBinding(root, dp, newBinding);
BindingExpression nuExp = root.GetBindingExpression(dp);
m_bindings.Add(nuExp);
}
}
}
}
}
int children = VisualTreeHelper.GetChildrenCount(root);
for(int i = 0; i < children; i++)
{
FrameworkElement child = VisualTreeHelper.GetChild(root, i) as FrameworkElement;
if(child != null)
GetBindings(child);
}
}
这里我将模式更改为OneTime,将UpdateSourceTrigger更改为Explicit。
public static Binding CreateOneTimeBinding(Binding binding, object source)
{
var result = new Binding
{
Source = source,
AsyncState = binding.AsyncState,
BindingGroupName = binding.BindingGroupName,
BindsDirectlyToSource = binding.BindsDirectlyToSource,
Converter = binding.Converter,
ConverterCulture = binding.ConverterCulture,
ConverterParameter = binding.ConverterCulture,
//ElementName = binding.ElementName,
FallbackValue = binding.FallbackValue,
IsAsync = binding.IsAsync,
Mode = BindingMode.OneWay,
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 = UpdateSourceTrigger.Explicit,
ValidatesOnDataErrors = binding.ValidatesOnDataErrors,
ValidatesOnExceptions = binding.ValidatesOnExceptions,
XPath = binding.XPath,
};
foreach(var validationRule in binding.ValidationRules)
result.ValidationRules.Add(validationRule);
return result;
}
当用户通过NumericUpDown更改目标值时,BindingExpression的DataItem属性将设置为null。然后,当我在BindingExpression上调用下面的UpdateSource()时,抛出一个异常,说:“分离绑定时无法执行此操作。”
void ApplyClicked(object sender, RoutedEventArgs e)
{
foreach(BindingExpression express in m_bindings)
express.UpdateSource();
}
我做错了什么?
答案 0 :(得分:2)
我发现了问题。数据绑定需要具有TwoWay(或OneWayToSource)模式才能更新源。因此,在上面的代码中,唯一需要改变的是将OneWay更改为TwoWay。