Forum

WPF pluging dev problem

Hi guys,

I’m making a plug for wpf GUI, the base code came from an unfinished contrib.
It is spreadable now but if I increase the spreadcount to fast in the patch then I get an error :

00:00:15 ERR : Specified Visual is already a child of another Visual or the root of a CompositionTarget.

But if I increase the spreadcount slowly, then no problem. Looks like if UIElementIn.IsChanged is not fast enough at some point.

What do you think ?

Thank you

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.Integration;
using System.ComponentModel.Composition;
using VVVV.PluginInterfaces.V1;
using VVVV.PluginInterfaces.V2;
using VVVV.Utils.VColor;
using VVVV.Core.Logging;

namespace VVVV.Packs.UI.Nodes.WPF
{
    [PluginInfo(Author = "lecloneur", Name = "Renderer", Category = "WPF", Help = "Renders WPF elements and displays the UI", AutoEvaluate = true, InitialBoxHeight = 120, InitialBoxWidth = 160, InitialComponentMode = TComponentMode.InAWindow, InitialWindowHeight = 300, InitialWindowWidth = 400)](PluginInfo(Author = "lecloneur", Name = "Renderer", Category = "WPF", Help = "Renders WPF elements and displays the UI", AutoEvaluate = true, InitialBoxHeight = 120, InitialBoxWidth = 160, InitialComponentMode = TComponentMode.InAWindow, InitialWindowHeight = 300, InitialWindowWidth = 400))

    public class WPFRendererNode : System.Windows.Forms.UserControl, IPluginEvaluate, IUserInputWindow
    {
        [Input("Background Color", DefaultColor = new[](Input("Background Color", DefaultColor = new[) {0.94, 0.94, 0.94, 1.0}, IsSingle = true, HasAlpha = false, Order = 1)]
        public IDiffSpread<RGBAColor> ColorIn;

        [Input("Element", Order = 0)](Input("Element", Order = 0))
        public IDiffSpread<UIElement> UIElementIn;

        [Output("Height", AsInt = true, IsSingle = true, Order = 1)](Output("Height", AsInt = true, IsSingle = true, Order = 1))
        public ISpread<int> HeightOut;

        [Output("Width", AsInt = true, IsSingle = true, Order = 0)](Output("Width", AsInt = true, IsSingle = true, Order = 0))
        public ISpread<int> WidthOut;

        [Import()](Import())
        public ILogger FLogger;

        private readonly ElementHost _container = new ElementHost { Dock = System.Windows.Forms.DockStyle.Fill };

        public WPFRendererNode()
        {
            Controls.Clear();
            _container.Child = new Grid();
            Controls.Add(_container);
        }

        public void Evaluate(int SpreadMax)
        {
            var child = (Grid)_container.Child;

            WidthOut[0](0) = _container.Width;
            HeightOut[0](0) = _container.Height;

            for (var i = 0; i < SpreadMax; i++)
            {
                if (ColorIn.IsChanged)
                    _container.BackColor = ColorIn[i](i).Color;
            }

            if (UIElementIn.IsChanged)
            {
                child.Children.Clear();
                for (var i = 0; i < SpreadMax; i++)
                {
                    child.Children.Add(UIElementIn[i](i));
                }

                int log = child.Children.Count;
                string logg = log.ToString();
                string spreadmax = SpreadMax.ToString();
                FLogger.Log(LogType.Debug, logg + " : Slider" + " Spread size = "+spreadmax);
            }       
        }
        public IntPtr InputWindowHandle
        {
            get { return _container.Handle; }
        }
    }
}

post the whole thing.
easier to find the bugger, than looking at pic of the patch. might also be something at SliderTest, depending on how you create the spread there.

Ok,

here is the VS project and test patch.

VVVV.Packs_.UI-Test.zip (2.7 MB)

hey lecloneur!

make sure that an uielement that already has a parent is not added again.

something like:

// didn't try the code though

                child.Children.Clear();
                for (var i = 0; i < SpreadMax; i++)
                {
                    var e = UIElementIn[i](i);
                    if (e.VisualParent == null)
                      child.Children.Add(e); 
                }

with

  • magic modulo,
  • getslice and what not
  • a second renderer
    it is easy to patch a scenario where one single slider appears on different renderer slices. so you have to check by yourself that a slider is not already added. I don’t know if this happens to be the problem here though.

the issue comes from within SliderTest

41 if (UIElementOut == null || !(UIElementOut[i](i) is Slider))

you don’t create a new instance of slider, if the slice already has one.

and in the renderer you keep adding all the input slices into the container

58 child.Children.Add(UIElementIn[i](i));

this way you just add all elements if any changed on top of the old ones.
even if you cleared the container, you’d still have an issue to reassign uielements to the container, because there’s no check, if the element is already in the container.

Be aware of the performance using wpf in debug mod that node is pulling 1000 clicks, I seem to remember trying something like this last year, and the performance being quite bad…

guys thanks for your input. I’m really new to this so I need a lot of time to code few lines (not use to C#, neither WPF).

Woei, tell me if I’m wrong, IsChanged is called anytime something happen in the input pin, so while SliceCount is changing IsChanged is true as well, means something is added while there is potentialy no slider added in the slidernode.

Thing is, I don’t see how I fix that at all… any idea ?

thanks

P.S @cat, I know wpf is definitely not the best performance wise, but it can’t be worst than the actual vvvv gui, also I don’t know what else I could use.

Hi clone,
Sorry for the late reply…Almost forgot…

Changed a little bit code in SliderTest.cs and RendererNode.cs and it works fine on my pc.

check the attachment.

VVVV.Packs_.UI-Test.rar (2.3 MB)

ok thanks to agalloch who is joining force from time to time, I’m making great progress and I have now press button, toggle button, dialog open, slider and textbox fully spreadable and usable with a custom WPF “group” node and renderer.

Now i’m working on “Tab” node and when I open vvvv for testing, everything is displayed correctly but if I try to switch between tab by clicking on it, then the WPF window stop working and TTY says :

the exception is here : http://pastebin.com/f9Y04J2J

sadely I didn’t find anything about this problem on the web, maybe you guys have an idea ?

Thank you