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:
- add references to
RealTimeGraphX
andRealTimeGrpahX.WPF
in my project - copy the class
WpfGraphControl.cs
that defines the"Controller"
DependencyProperty
into my project - instantiate a controller in my
XAML
file as it is in the demo:<myClass:WpfGraphControl Controller="{Binding Controller}"
- 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.
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:
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
.
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
.
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:
- The referenced project must be of type "WPF Custom Control Library" (not WPF User Control Library).
- 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.