Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Range Binding CustomAxis

Solved!
Go to solution

Hi,

 

I am using an IntensityGraph with a custom time Axis from M21259, however I have troubles getting the range binding to work properly. I am using InteractionMode="EditRange", but when range is changed I get no call to the binding method (range is changed by editing directly on time axis during runtime). All is configured in xaml using: <local:CustomAxis StartTime ="{Binding WaterfallStartTime}" Range="{Binding WaterFallRange}"  InteractionMode="EditRange" Adjuster="ContinuousChart" >. If I instead add a callback, i.e. RangeChanged="CustomAxis_RangeChanged" this is working, but since I use MVVM this is not preferred. Am I doing something wrong? I can provide a simple running code if that helps. Thanks!

 

Brg.

 

Oddvar

0 Kudos
Message 1 of 5
(1,397 Views)

In this case, you need to explicitly tell WPF you want a two-way binding: Range="{Binding WaterFallRange, Mode=TwoWay}"

~ Paul H
0 Kudos
Message 2 of 5
(1,361 Views)

Hi,

 

I am afraid I already tried that without success. Added a simple running example, hope this helps. Try to change the end time of the time axis, I can't get it to call the Range binding. Another issue I don't understand is that if you first try to edit the start time of the time axis this doesn't work, it is set back to 00:00 again. You need to edit end time before start time. Why? Is it some sort of initialization issue?

 

Brg.

 

Oddvar

0 Kudos
Message 3 of 5
(1,352 Views)
Solution
Accepted by topic author OddvarC

Thank you for the simple code example! Running in debug, I see this error in the Output window:


System.Windows.Data Error: 1 : Cannot create default converter to perform 'two-way' conversions between types 'NationalInstruments.Controls.Range`1[System.DateTime]' and 'NationalInstruments.Controls.Range`1[System.Double]'.

The custom axis is designed to display values as time by telling the graph that the data source uses DateTime values, but the actual data type of the range is still double, not DateTime. The binding either needs a Range<double> property to act as the source, or a converter to translate between double data and DateTime display types (similar to the logic in the custom formatter).


As for the issues with range editing, this stems from the how DateTime parses time-only value. Given a string with just a time (e.g. "12:34:56"), parse will return DateTime.Now.Date plus that time. But the custom axis is configured with DateTime.MinValue as the start, so the returned parse value will be much larger for whatever time is entered, and the axis will reject attempts to edit the minimum to be above the maximum.

 

To fix this, you can set the EditRangeValueFormatter to a value that includes both the date and the time:

 

<local:CustomAxis.MajorDivisions>
    <ni:RangeLabeledDivisions>
        <ni:GeneralValueFormatter Format="HH:mm:ss" />
        <ni:RangeLabeledDivisions.EditRangeValueFormatter>
            <ni:GeneralValueFormatter Format="G" />
        </ni:RangeLabeledDivisions.EditRangeValueFormatter>
    </ni:RangeLabeledDivisions>
</local:CustomAxis.MajorDivisions>

 

Or you can create a custom formatter with additional logic to use the existing date value and add just the newly parsed time value, to keep the same text when displaying or editing an axis division.


Aside: I see you created a dependency property for StartTime on the custom axis. Just two notes: as the dependency property type is DateTime, the accessor can also be updated to the non-nullable type to match; and using the dependency property change callback is the appropriate way to do invalidation, so no need to also invalidate in the property setter.

 

public DateTime StartTime
{
    get { return (DateTime)GetValue(StartTimeProperty); }
    set { SetValue(StartTimeProperty, value); }
}

 

~ Paul H
0 Kudos
Message 4 of 5
(1,349 Views)

Thanks for this Paul! I didn't notice that I could see the error in the output window! Changed to double and added a converter and now it works perfectly.


Regarding the issues with range editing, this explains why it works when I initialize the range with values :-). Thanks for explaining!


Thanks for the information regarding the StartTime, I see that  this of course is covered by the dependency property change callback. Copied this from an example where dependency was not used and didn't notice this.

 

Brg.

 

Oddvar

0 Kudos
Message 5 of 5
(1,335 Views)