icsharpcode / WpfDesigner

The WPF Designer from SharpDevelop
MIT License
958 stars 259 forks source link

Properties of Component bound to directly not reflected in DesignItem.Properties #61

Closed JoshWobbles closed 5 years ago

JoshWobbles commented 5 years ago

So I get why changes made directly to the Component's Properties dont propagate back into the DesignItem Properties wrapper, but is there any other way for changes to be reflected? I am trying to bind a couple additional controls to attached properties of a UI Element I am drawing, but since I am not binding directly to the accessors (nor do I think that is possible) the changes do not make their way into the xaml.

jogibear9988 commented 5 years ago

From where should we know wich Properties of a WPF Control are set via Styles, via Code,... where should we know wich Properties we should use and wich not. I think it would easily be possible to create a Helper class wich takes over all Properties, but that will result in a huge xaml file... Or you could try only to set the Propertys where ReadLocalValue(xxxProperty) != DependencyProperty.UnsetValue;

jogibear9988 commented 5 years ago

And you can always set the properties manually via code:

This is some code used in our system:

                    var rectangle = new SignalValueDisplay();
                    var rectDesItem = rootItem.Services.Component.RegisterComponentForDesigner(rectangle);
                    rectDesItem.Properties.GetProperty(FrameworkElement.WidthProperty).SetValue(conveyor.Width);
                    rectDesItem.Properties.GetProperty(FrameworkElement.HeightProperty).SetValue(20);
                    rectDesItem.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(conveyor.GetValue(Canvas.LeftProperty));
                    rectDesItem.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(Canvas.GetTop(conveyor) + conveyor.Height - 46);
                    rectDesItem.Properties.GetProperty(SignalValueDisplay.TextAlignmentProperty).SetValue(TextAlignment.Center);
                    rectDesItem.Properties.GetProperty(SignalValueDisplay.SignalNameProperty).SetValue(".PLACES." + (char.IsNumber(conveyor.ObjectName[0]) ? "P" : "") + conveyor.ObjectName + ".DATAFIELDS.ID");
                    rectDesItem.Properties.GetProperty(SignalValueDisplay.BackgroundReadonlyProperty).SetValue(Brushes.White);

                    var positionConveyor = designItem.Parent.ContentProperty.CollectionElements.IndexOf(designItem);
                    var idx = ++positionConveyor;
                    designItem.Parent.ContentProperty.CollectionElements.Insert(idx, rectDesItem);
JoshWobbles commented 5 years ago

I figured it out, feels hackish but I wrapped a local property around the get and set accestors like so:

        public string dataSource
        {
            get { return (string)designSurface.DesignContext.Services.Selection.SelectedItems.FirstOrDefault()?.Properties.GetAttachedProperty(AttachedProperties.DataSourceProperty)?.ValueOnInstance; }
            set { designSurface.DesignContext.Services.Selection.SelectedItems.FirstOrDefault()?.Properties.GetAttachedProperty(AttachedProperties.DataSourceProperty)?.SetValue(value); }
        }

Feels off, but it works