08-25-2015 09:09 AM
This code worked at MS 2013:
public class MyGeneralValueFormatter : GeneralValueFormatter
{
return Engineering.ToFormattedString(Convert.ToDouble(value), this.Format, _units);
}
protected override UIElement VisualizeCore<TData>(TData value, ValuePresenterArgs args, UIElement existingVisual)
{
UIElement element = base.VisualizeCore<TData>(value, args, existingVisual);
if (args.Context is Axis<TData>)
{
var axis = (Axis<TData>)args.Context;
if (axis.Orientation == System.Windows.Controls.Orientation.Horizontal)
{
if (_showOnlyMinMaxAtX)
{
Range<TData> range = axis.Range;
var comparer = range.Comparer;
RelativeAlignment alignment =
comparer.Compare(range.Minimum, value) == 0 ? RelativeAlignment.Near :
comparer.Compare(range.Maximum, value) == 0 ? RelativeAlignment.Far :
RelativeAlignment.Center;
//RegionPanel.SetRelativeHorizontalAlignment(element, alignment);
element.Opacity = comparer.Compare(range.Minimum, value) == 0 || comparer.Compare(range.Maximum, value) == 0 ? 1.0 : 0.0;
}
}
else
{
element = new Viewbox { MaxWidth = 60, Width = 60, Stretch = System.Windows.Media.Stretch.None, Child = element };
}
}
return element;
}
}
1. This doesn't even compile:
RegionPanel.SetRelativeHorizontalAlignment(element, alignment);
2. This crashes with error: Specified element is already the logical child of another element. Disconnect it first.
element = new Viewbox { MaxWidth = 60, Width = 60, Stretch = System.Windows.Media.Stretch.None, Child = element };
Solved! Go to Solution.
08-25-2015 10:17 AM
Hi, eugenem
I can address one of your concerns immediately. In Measurement Studio 2015, RegionPanel was changed to RelativePanel, which is why that line no longer compiles.
To address your other concern, I will need more context for this code. Syntactically, I don't believe your code (as is) would have compiled in any version of Visual Studio. It is also unclear how the value formatter class relates to the VisualizeCore<TData> override method. Can you please provide a more complete snippet? Please see the following copy of the code you provided, where I have added comments with questions. I also highlighted the place I changed RegionPanel to RelativePanel.
// This is a class definition. Why is it returning a value?
public class MyGeneralValueFormatter : GeneralValueFormatter
{
return Engineering.ToFormattedString(Convert.ToDouble(value), this.Format, _units);
}
// Where does this method belong? Currently it does not have a containing class.
protected override UIElement VisualizeCore<TData>(TData value, ValuePresenterArgs args, UIElement existingVisual)
{
UIElement element = base.VisualizeCore<TData>(value, args, existingVisual);
if (args.Context is Axis<TData>)
{
var axis = (Axis<TData>)args.Context;
if (axis.Orientation == System.Windows.Controls.Orientation.Horizontal)
{
if (_showOnlyMinMaxAtX)
{
Range<TData> range = axis.Range;
var comparer = range.Comparer;
RelativeAlignment alignment =
comparer.Compare(range.Minimum, value) == 0 ? RelativeAlignment.Near :
comparer.Compare(range.Maximum, value) == 0 ? RelativeAlignment.Far :
RelativeAlignment.Center;
RelativePanel.SetRelativeHorizontalAlignment(element, alignment);
element.Opacity = comparer.Compare(range.Minimum, value) == 0 || comparer.Compare(range.Maximum, value) == 0 ? 1.0 : 0.0;
}
}
else
{
element = new Viewbox { MaxWidth = 60, Width = 60, Stretch = System.Windows.Media.Stretch.None, Child = element };
}
}
return element;
}
}
08-25-2015 10:24 AM
sorry, I've deleted too much of the class. there is the full version:
public class RCAGeneralValueFormatter : GeneralValueFormatter
{
private string _units;
private bool _showOnlyMinMaxAtX;
public RCAGeneralValueFormatter(string format, string units, bool showOnlyMinMaxAtX)
: base(format)
{
_units = units;
_showOnlyMinMaxAtX = showOnlyMinMaxAtX;
}
protected override string FormatCore<TData>(TData value, ValuePresenterArgs args)
{
if (args.Context is Axis<TData>)
{
var axis = (Axis<TData>)args.Context;
if (axis.Orientation == System.Windows.Controls.Orientation.Horizontal)
{
Range<TData> range = axis.Range;
var comparer = range.Comparer;
if( comparer.Compare(range.Minimum, value) != 0 && comparer.Compare(range.Maximum, value) != 0)
return Engineering.ToFormattedString(Convert.ToDouble(value), this.Format, "");
}
}
return Engineering.ToFormattedString(Convert.ToDouble(value), this.Format, _units);
}
protected override UIElement VisualizeCore<TData>(TData value, ValuePresenterArgs args, UIElement existingVisual)
{
UIElement element = base.VisualizeCore<TData>(value, args, existingVisual);
if (false && args.Context is Axis<TData>)
{
var axis = (Axis<TData>)args.Context;
if (axis.Orientation == System.Windows.Controls.Orientation.Horizontal)
{
if (_showOnlyMinMaxAtX)
{
Range<TData> range = axis.Range;
var comparer = range.Comparer;
RelativeAlignment alignment =
comparer.Compare(range.Minimum, value) == 0 ? RelativeAlignment.Near :
comparer.Compare(range.Maximum, value) == 0 ? RelativeAlignment.Far :
RelativeAlignment.Center;
//RegionPanel.SetRelativeHorizontalAlignment(element, alignment);
element.Opacity = comparer.Compare(range.Minimum, value) == 0 || comparer.Compare(range.Maximum, value) == 0 ? 1.0 : 0.0;
}
}
else
{
element = new Viewbox { MaxWidth = 60, Width = 60, Stretch = System.Windows.Media.Stretch.None, Child = element };
}
}
return element;
}
}
08-25-2015 02:49 PM
Thank you for posting the rest of the code.
It looks like instead of using your override for VisualizeCore<TData>, you can make use of the new properties, RangeLabeledDivisions.MaximumLabelAlignment and RangeLabeledDivisions.MinimumLabelAlignment. For example:
<ni:Graph>
<ni:Graph.Axes>
<ni:AxisDouble Orientation="Horizontal">
<ni:AxisDouble.MajorDivisions>
<ni:RangeLabeledDivisions MaximumLabelAlignment="Far" MinimumLabelAlignment="Near" />
</ni:AxisDouble.MajorDivisions>
</ni:AxisDouble>
</ni:Graph.Axes>
</ni:Graph>
As for creating a new ViewBox, is there a reason you don't just set the UIElement properties directly on element? It seems like setting the MaxWidth on element would have the same effect as what you are doing there.