質問

I am trying to produce a graph and with the x axis and y axis display ranges defined by the calculated data in my c# code. I wanted to set the x axis range at 50 centered at a particular value (SpotValue), and I wanted to set the y axis range to be between the min and the max of the data the lineseries is displaying.

I have used the same approach for binding the axis ranges but for some reason it is working for the x axis but not the y axis. What's really strange is that if I replace the CallDeltaVector.Min() and CallDeltaVector.Max() with numbers, the graph picks up the correct y axis range.

I can't seem to figure out why this isn't working with the .Min() and .Max() functions. I tried searching thoroughly and did not find a similar issue anywhere. Any help would be greatly appreciated.

I have the following XAML

    <charting:Chart 
        x:Name="CallDeltaGraph" Title="Call Delta" 
        Background="Black" Foreground="WhiteSmoke" 
        FontWeight="Bold" BorderBrush="WhiteSmoke" 
        BorderThickness="3" Width="350" Height="350" 
        VerticalAlignment="Top" HorizontalAlignment="Left" 
        Margin="786,82,0,0">
            <charting:Chart.LegendStyle>
                <Style TargetType="Control">
                    <Setter Property="Width" Value="0" />
                    <Setter Property="Height" Value="0" />
                </Style>
            </charting:Chart.LegendStyle>
            <charting:Chart.Axes>
                <charting:LinearAxis 
                    x:Name="CallDeltaGraphXAxis" 
                    Orientation="X" Minimum="{Binding Path=Key}" 
                    Maximum="{Binding Path=Value}" ShowGridLines="True"/>
                <charting:LinearAxis 
                    x:Name="CallDeltaGraphYAxis"  
                    Orientation="Y" Minimum="{Binding Path=Key}" 
                    Maximum="{Binding Path=Value}" ShowGridLines="True" />
            </charting:Chart.Axes>
            <charting:Chart.Series>
                <charting:LineSeries 
                    IndependentValueBinding="{Binding Path=Key}" 
                    DependentValueBinding="{Binding Path=Value}" />
            </charting:Chart.Series>
        </charting:Chart>

and I have the following c# code:

    KeyValuePair<double, double>[] XRange = new KeyValuePair<double, double>[1];
    XRange[0] = new KeyValuePair<double, double>(Math.Floor(SpotPrice) - 25, Math.Ceiling(SpotPrice) + 25);
    CallDeltaGraphXAxis.DataContext = XRange;

    KeyValuePair<double, double>[] CallDeltaYRange = new KeyValuePair<double, double>[1];
    CallDeltaYRange[0] = new KeyValuePair<double, double>(CallDeltaVector.Min(), CallDeltaVector.Max());
    CallDeltaGraphYAxis.DataContext = CallDeltaYRange;
役に立ちましたか?

解決 2

If you change

KeyValuePair<double, double>[] CallDeltaYRange = new KeyValuePair<double, double>[1];
    CallDeltaYRange[0] = new KeyValuePair<double, double>(CallDeltaVector.Min(), CallDeltaVector.Max());
    CallDeltaGraphYAxis.DataContext = CallDeltaYRange;

to instead create an instance of this class...

    CallDeltaYRangeInfo cvRange = new CallDeltaYRangeInfo{Ymax = CallDeltaVector.Max(), Ymin = CallDeltaVector.Min()};

Where the class is defined like...

public class CallDeltaYRangeInfo : INotifyPropertyChanged
{
    private double _yMin;
    public double Ymin
    {
        [DebuggerStepThrough]
        get { return _yMin; }
        [DebuggerStepThrough]
        set
        {
            if (Math.Abs(value - _yMin) > 1e-6)
            {
                _yMin = value;
                OnPropertyChanged("Ymin");
            }
        }
    }
    private double _yMax;
    public double Ymax
    {
        [DebuggerStepThrough]
        get { return _yMax; }
        [DebuggerStepThrough]
        set
        {
            if (Math.Abs(value - _yMax) > 1e-6)
            {
                _yMax = value;
                OnPropertyChanged("Ymax");
            }
        }
    }
    #region INotifyPropertyChanged Implementation
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string name)
    {
        var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    #endregion
}

... then you can assign CallDeltaGraphYAxis.DataContext to that instance and you will see a better result.

      <charting:LinearAxis x:Name="CallDeltaGraphYAxis"  Orientation="Y" Minimum="{Binding Ymin}" Maximum="{Binding Ymax}"  ShowGridLines="True" />

他のヒント

Hmm ... very puzzling your code ... First of all, you use a KeyValuePair<double, double> in order to then just use it as key- value, but those are really Min and Max, so it's misleading.

Second, you have this:

Minimum="{Binding Path=Key}" Maximum="{Binding Path=Value}"

So the binding looks for a property called Key and one called Value, but you don't have them ... what you have are key and value on your KeyValuePair.

I guess you can bind to the KeyValuePair and give it the key or value as relative path, something along:

 <Binding  ElementName=your_object, Path=key_or_value>

or MUCH BETTER: have a property called MinVal, one called MaxVal, and bind to them ...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top