当UI元素数据更改时,WPF一次性数据绑定将分离
我正在尝试在NumericUpDown的value属性和cs对象的属性之间设置数据绑定。NumericUpDown位于模式对话框中,因此我只希望在用户按下OK按钮时更新数据绑定。这个NumericUpDown位于PropertyGrid中,它在非模态对话框中工作良好,因此我不想修改最初创建数据绑定的XAML。我也不想为了改变数据绑定而复制XAML。因此,我试图复制和修改模态对话框的已加载事件处理程序中的数据绑定 在这里,我复制并修改最初在XAML中创建的数据绑定当UI元素数据更改时,WPF一次性数据绑定将分离,wpf,data-binding,Wpf,Data Binding,我正在尝试在NumericUpDown的value属性和cs对象的属性之间设置数据绑定。NumericUpDown位于模式对话框中,因此我只希望在用户按下OK按钮时更新数据绑定。这个NumericUpDown位于PropertyGrid中,它在非模态对话框中工作良好,因此我不想修改最初创建数据绑定的XAML。我也不想为了改变数据绑定而复制XAML。因此,我试图复制和修改模态对话框的已加载事件处理程序中的数据绑定 在这里,我复制并修改最初在XAML中创建的数据绑定 void OnLoad(
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);
}
}
当用户通过NumericUpDown更改目标值时,BindingExpression的DataItem属性将设置为null。然后,当我在下面对该BindingExpression调用UpdateSource()时,会引发一个异常,该异常表示:“分离绑定时无法执行此操作。”
我做错了什么 我发现了问题。数据绑定需要具有双向(或单向到源)模式才能更新源。因此,在上面的代码中,唯一需要更改的是将单向更改为双向。每个贴子下面都需要有一个按钮,标签为“向我们展示该死的代码”。如果有“当我更改UI元素值时…”,我会立即按下它?如果明确修改元素的值,绑定将分离。你的意思是你正在更新绑定值吗?是的,当我说“我更改UI元素”时,我的意思是我正在通过UI元素修改绑定的目标值。
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;
}
void ApplyClicked(object sender, RoutedEventArgs e)
{
foreach(BindingExpression express in m_bindings)
express.UpdateSource();
}