NumericUpDown의 value 속성과 cs 개체의 속성 사이에 데이터 바인딩을 설정하려고합니다. NumericUpDown은 모달 대화 상자에 있으므로 사용자가 확인 버튼을 누르면 데이터 바인딩이 업데이트되기를 원합니다. 이 NumericUpDown은 모달이 아닌 대화 상자 상황에서 제대로 작동하는 PropertyGrid에 있으므로 원래 데이터 바인딩을 만든 XAML을 수정하고 싶지 않습니다. 또한 데이터 바인딩을 변경하기 위해 XAML을 복제하기를 원하지 않습니다. 그래서, 복사 및 모달 대화 상자의로드 된 이벤트 처리기에서 데이터 바인딩을 수정하려면 노력하고있어.UI 요소 데이터가 변경되면 WPF OneTime 데이터 바인딩이 분리됩니다.
여기에서 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으로 변경합니다. 사용자가 NumericUpDown 통해 BindingExpression있는 DataItem의 특성을 목표 값을 변경
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;
}
은 널로 설정 얻는다. 그런 다음 그 BindingExpression 아래 UpdateSource()를 호출하면 "바인딩이 분리되면이 작업을 수행 할 수 없습니다."라는 예외가 발생합니다.
void ApplyClicked(object sender, RoutedEventArgs e)
{
foreach(BindingExpression express in m_bindings)
express.UpdateSource();
}
내가 뭘 잘못하고 있니?
모든 게시물 아래에 "Frigging Code 표시"라는 버튼이 있어야합니다. 나는 지금 당장 그것을 눌러야한다. –
"UI 요소 값을 변경할 때 ..."? 요소의 값을 명시 적으로 수정하면 바인딩이 분리됩니다. 바운드 값을 업데이트한다는 의미입니까? –
예, "UI 요소를 변경합니다"라고 말하면 UI 요소를 통해 바인딩의 대상 값을 수정하고 있음을 의미합니다. – Hank