royben/RealTimeGraphX

Cannot transfer WPF demo into my own app...

dmedine opened this issue · 18 comments

This is a really slick and nice graphing tool! I am having some trouble, however, understanding how to transfer the demo into my own application.

These are the steps I took:

  1. add references to RealTimeGraphX and RealTimeGrpahX.WPF in my project
  2. copy the class WpfGraphControl.cs that defines the "Controller" DependencyProperty into my project
  3. instantiate a controller in my XAML file as it is in the demo: <myClass:WpfGraphControl Controller="{Binding Controller}"
  4. define a public WpfGraphController<Type, Type> Controller property in my view model code

The result is an empty control where the graph should be. I am sure that the calls to Controller.PushData are being hit, because when I step in with the debugger, the data is going in.

Here is a pic:
rtx_fail

I am able to draw the graph if instead of using <myClass:WpfGraphControl Controller... I instead use <rtx:WpfGraphSurface... (where rtx points to the namespace defined as xmlns:rtx="clr-namespace:RealTimeGraphX.WPF;assembly=RealTimeGraphX.WPF") in my XAML file, but then it only shows the line plot. There are no axes, labels, or any of the other good stuff:
rtx_sorta

I Also tried to use rtx:WpfGraphController but this was met with an error. What am I missing here?

You are missing the Generic.xaml file from the demo.
This file contains the style and template of the WpfGraphControl.

I am still unable to get this to work. I added Generic.xaml to my project and changed the local namespace in that file so that it matches the one in my copy of WpfGraphControl.cs. It builds without error or warning but no there are again no graphs.

One clue is that when I peek the definition for WpfGraphControl in my code, it sends me directly to the definition of the class in WpfGraphControl.cs.

mine

When I do the same in your demo project, I am directed to that and the namespace for the class that is declared in Generic.xaml.

yours

Somehow I am not connecting up the style and template for WpfGraphControl, but I can't figure out what the problem is. Any ideas as to what is missing are most appreciated.

It seems like you are missing some WPF fundamentals.
If you wish, attach an example project and I will investigate and layout what you are missing.

That is most kind of you. I am still new to WPF, but I would say that this is pretty advanced usage, rather than fundamentals ;-)

I will try to work it out some more before bothering you with my project. Thanks again for the offer, though.

Ok. I have made some progress now. I had to explicitly tell my User Control to open up the resource dictionary in Generic.xaml.

Adding the following put the graph on the control:

    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Themes/Generic.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

I still don't understand why this isn't necessary in your project---or maybe I just can't find it. I am targetting .NET Framework 4.5, but I don't see why that should matter.

Your comments and help are most appreciated!

If a WPF application reference another WPF custom control project, it will automatically import the "Generic.xaml" file.
This is a convention that is valid only on the following terms:

  1. The referenced project must be of type "WPF Custom Control Library" (not WPF User Control Library).
  2. The Generic.xaml file must be under the "Themes" folder at the referenced project.

If you are using the same project to do all the work that is something else.
I can't really tell your solution arrangement.

Aha. That makes sense then. Mine is a user control library not a custom control library. Otherwise, the setup is the same.

There must be a way to tell Visual Studio to do this, though. I've never done it before but I see now that when you create a Custom Control class it automatically generates the Generic.xaml file in a Themes folder. It would be good to know how to tell Visual Studio to make these links without the wizard. Since I simply copied your Themes/Generic.xaml and WpfGraphControl.cs into my project this association doesn't exist.

Actually, if the offer still stands I do need some help. I can now put the control on the window so that the grid shows, but I still cannot plot anything on the grid. The expected time and data values are going into the calls to Controller.PushData but nothing changes on my screen.

I made a mockup of what I am trying to do and pushed it here: https://github.com/dmedine/testingRTX. It should run straight away except the references to RealTimeGraphX dlls are absolute paths on my machine and will have to be changed.

I have been through it over and over and I can't figure out what the problem is.

From a light inspection, without actually running, I see that you are binding your "GraphController" object to the WpfGraphControl "Controller" property, while actually the Controller property expects the library IGraphController interface.
This binding is totally wrong.

Try replacing this:

<top:WpfGraphControl Margin="10" Controller="{Binding GraphController}" />

With this:

<top:WpfGraphControl Margin="10" Controller="{Binding GraphController.Controller}" />

Yes, indeed this is correct! This binding did strike me as odd and I did not understand how this mechanism worked. I was just naively following your example.

Just out of curiosity, for a WPF newb like myself, can you explain how you are able to bind here:
https://github.com/royben/RealTimeGraphX/blob/master/RealTimeGraphX.WPF.Demo/MainWindow.xaml#L37
with
<local:WpfGraphControl x:Name="graph" Margin="10" Controller="{Binding Controller}" />

and not

<local:WpfGraphControl x:Name="graph" Margin="10" Controller="{Binding Controller.Controller}" />

because again, the Controller object in MainWindowVM is of type WpfGrpahController <T1,T2>, not IGraphController.

ps, thanks again!

WpfGraphController inherits from IGraphController.

I am an idiot. I see what I did now. Now this makes sense.

One more question. I have now set the controller properties thus:

Controller = new WpfGraphController<TimeSpanDataPoint, DoubleDataPoint>();
Controller.Range.MinimumY = 0;
Controller.Range.MaximumY = 1080;
Controller.Range.MaximumX = TimeSpan.FromSeconds(10);
Controller.Range.AutoY = false;

but when I start running the app, the Y scale keeps growing. Min and Max stay the same, but the space between tics gets bigger and bigger an the scrollbar gets smaller and smaller.

Oh, I think it is because of the WPF Grid dimensions.

Yeah, doesn't work with the Scrollbar.

It can probably work with a scrollbar, you just need the right layout.