WPF binding OneWayToSource sets source property to “” when the DataContext is changed

前端 未结 5 2049
再見小時候
再見小時候 2021-01-19 00:22

I have a OneWayToSource binding that is not behaving as I expected when I set the DataContext of the target control. The property of the source is being set to default inste

5条回答
  •  忘掉有多难
    2021-01-19 00:54

    You need Attached property:

    public static readonly DependencyProperty OneWaySourceRaiseProperty = DependencyProperty.RegisterAttached("OneWaySourceRaise", typeof(object), typeof(FrameworkElementExtended), new FrameworkPropertyMetadata(OneWaySourceRaiseChanged));
    
            public static object GetOneWaySourceRaise(DependencyObject o)
            {
                return o.GetValue(OneWaySourceRaiseProperty);
            }
    
            public static void SetOneWaySourceRaise(DependencyObject o, object value)
            {
                o.SetValue(OneWaySourceRaiseProperty, value);
            }
    
            private static void OneWaySourceRaiseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if (e.NewValue == null)
                    return;
    
                var target = (FrameworkElement)d;
                target.Dispatcher.InvokeAsync(() =>
            {
                var bindings = target.GetBindings().Where(i => i.ParentBinding?.Mode == BindingMode.OneWayToSource).ToArray();
                foreach (var i in bindings)
                {
                    i.DataItem.SetProperty(i.ParentBinding.Path.Path, d.GetValue(i.TargetProperty));
                }
            });
    

    And set binding in XAML:

    extendends:FrameworkElementExtended.OneWaySourceRaise="{Binding}"
    

    where {Binding} - is binding to DataContext. You need:

        public static IEnumerable GetBindings(this T element, Func func = null) where T : DependencyObject
                {
                    var properties = element.GetType().GetDependencyProperties();
                    foreach (var i in properties)
                    {
                        var binding = BindingOperations.GetBindingExpression(element, i);
                        if (binding == null)
                            continue;
                        yield return binding;
                    }
                }
    
    
    private static readonly ConcurrentDictionary DependencyProperties = new ConcurrentDictionary();
        public static DependencyProperty[] GetDependencyProperties(this Type type)
                {
                    return DependencyProperties.GetOrAdd(type, t =>
                    {
                        var properties = GetDependencyProperties(TypeDescriptor.GetProperties(type, new Attribute[] { new PropertyFilterAttribute(PropertyFilterOptions.All) }));
                        return properties.ToArray();
                    });
                }
    
                private static IEnumerable GetDependencyProperties(PropertyDescriptorCollection collection)
                {
                    if (collection == null)
                        yield break;
                    foreach (PropertyDescriptor i in collection)
                    {
                        var dpd = DependencyPropertyDescriptor.FromProperty(i);
                        if (dpd == null)
                            continue;
                        yield return dpd.DependencyProperty;
                    }
                }
    

提交回复
热议问题