如何解决当UI元素数据发生更改时,WPF OneTime数据绑定将脱离
| 我正在尝试在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();
}
我究竟做错了什么?
解决方法
我发现了问题。数据绑定需要具有TwoWay(或OneWayToSource)模式才能更新源。因此,在上面的代码中,唯一需要更改的是将OneWay更改为TwoWay。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。