代码之家  ›  专栏  ›  技术社区  ›  Evan G

未在子网格中呈现oxyplot图

  •  0
  • Evan G  · 技术社区  · 7 年前

    我正在使用oxyplot wpf制作一个统计应用程序,用户在其中输入每个类的类限制和频率。然后选择要显示的4个图形中的哪一个。然后图表就会显示在那个白框中( 见下面的图像 )

    Statistics app GUI

    MainWindow 构造函数,我设置 this.DataContext = this . 我有一个 PlotModel 名为“MyModel”的属性,它绑定到 PlotView XAML代码中的控件( <oxy:PlotView Model="{Binding MyModel}"/> )。这个 绘图视图 在里面 Grid 称为“图形”,位于主视图内部 网格 (它在所有XAML代码的底部)。

    因此,当单击“显示”按钮时,在它的事件处理程序中,它将进入一个不同的if语句,根据哪个单选按钮进行检查。在每个if语句的末尾, this.MyModel 设置为 绘图模型 是在里面创造的。我认为通过写作 this.MyModel = model 它应该显示图表,但是当我测试它时,白色部分中没有任何东西呈现出来。 ( 查看以下所有代码 )

    我不确定这个问题是否是因为 this.MyModel= model 在子网格中或存在绑定问题。

    一般来说,我对WPF编程比较陌生,任何帮助都会受到感激。谢谢!

    主窗口.xaml:

    <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StatsApp"
        xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
        xmlns:oxy="http://oxyplot.org/wpf"
        xmlns:Properties="clr-namespace:StatsApp.Properties" x:Class="StatsApp.MainWindow"
        mc:Ignorable="d"
        Title="Frequency Distribution Graph Generator" Height="450" Width="800">
    
    <Grid Background="Gray">
    
        <Grid x:Name="Graph" HorizontalAlignment="Left" Height="306" Margin="340,39,0,0" VerticalAlignment="Top" Width="421">
            <oxy:PlotView Model="{Binding MyModel}"/>
        </Grid>
    
        <!-- I left out all the unnecessary textboxes and buttons ..... -->
    
    </Grid>
    

    MainWindow.cs:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
        }
    
        //private bool isfirstclick = true;
    
        public PlotModel MyModel { get; private set; }
    
        private void DisplayBtn_Click(object sender, RoutedEventArgs e)
        {
            // ---------------Retrieving Input START----------------
            TextBox[] lowerLimitsTxtBoxes =
            {
                Lower1TxtBox,
                Lower2TxtBox,
                Lower3TxtBox,
                Lower4TxtBox,
                Lower5TxtBox,
                Lower6TxtBox,
                Lower7TxtBox,
                Lower8TxtBox
            };
    
            TextBox[] upperLimitsTxtBoxes =
            {
                Upper1TxtBox,
                Upper2TxtBox,
                Upper3TxtBox,
                Upper4TxtBox,
                Upper5TxtBox,
                Upper6TxtBox,
                Upper7TxtBox,
                Upper8TxtBox
            };
    
            TextBox[] freqsTxtBoxes =
            {
                Freq1TxtBox,
                Freq2TxtBox,
                Freq3TxtBox,
                Freq4TxtBox,
                Freq5TxtBox,
                Freq6TxtBox,
                Freq7TxtBox,
                Freq8TxtBox
            };
    
            double[] lowerLimits = new double[8];
    
            for (int i = 0; i < lowerLimits.Length; i++)
            {
                if (Double.TryParse(lowerLimitsTxtBoxes[i].Text, out double lower))
                {
                    lowerLimits[i] = lower;
                }
                else
                {
                    lowerLimits[i] = -1;
                }
            }
    
    
            double[] upperLimits = new double[8];
    
            for (int i = 0; i < upperLimits.Length; i++)
            {
                if (Double.TryParse(upperLimitsTxtBoxes[i].Text, out double upper))
                {
                    upperLimits[i] = upper;
                }
                else
                {
                    upperLimits[i] = -1;
                }
            }
    
            //IMPORTANT -> The array of frequencies
            int[] freqs = new int[8];
    
            for (int i = 0; i < freqs.Length; i++)
            {
                if (Int32.TryParse(freqsTxtBoxes[i].Text, out int freq))
                {
                    freqs[i] = freq;
                }
                else
                {
                    freqs[i] = -1;
                }
            }
    
    
    
            int numClasses = 0;
    
            for (int i = 0; lowerLimits[i] != -1 && i < 8; i++)
            {
                numClasses++;
            }
    
            if (numClasses < 2)
            {
                throw new ArgumentException("Must use at least 2 classes");
            }
    
            //IMPORTANT -> The class marks array: double
            double[] classMarks = new double[numClasses];
            for (int i = 0; i < classMarks.Length; i++)
            {
                classMarks[i] = (lowerLimits[i] + upperLimits[i]) / 2.0;
            }
    
            //IMPORTANT -> The class marks array: string
            string[] classMarksString = new string[numClasses];
            for (int i = 0; i < numClasses; i++)
            {
                classMarksString[i] = classMarks[i] + "";
            }
    
            //----------Retrieving Input END--------------------
    
    
            if ((bool)ScatterRBtn.IsChecked)
            {
                var model = new PlotModel { Title = "Scatter Plot" };
                var scatter = new ScatterSeries { MarkerType = MarkerType.Circle };
                model.Axes.Add(new LinearAxis { Position = AxisPosition.Left,  Title = "Class Marks" });
                model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "Frequency" });
    
                for ( int i =0; i < numClasses; i++)
                {
                    scatter.Points.Add(new ScatterPoint(classMarks[i], freqs[i]));
                }
    
                model.Series.Add(scatter);
    
                //This doesn't update the graph even though I binded it in XAML code
                this.MyModel = model;
            }
            else if ((bool)RelativeFqRBtn.IsChecked)
            {
                var model = new PlotModel { Title = "Relative Frequency Polygon" };
                model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Maximum = 1, Title = "Class Marks" });
                model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "Frequency (%)" });
    
                var relativeFQ = new LineSeries();
    
                int frequencyTotal = 0;
    
                for (int i=0;  i < 8 && freqs[i] != -1 ; i++)
                {
                    frequencyTotal += freqs[i];
                }
    
                for (int i = 0; i < numClasses; i++)
                {
                    relativeFQ.Points.Add(new DataPoint(classMarks[i], freqs[i]/frequencyTotal ));
                }
    
                model.Series.Add(relativeFQ);
    
                //This doesn't update the graph even though I binded it in XAML code
                this.MyModel = model;
            }
            else if ((bool)CummuFqRBtn.IsChecked)
            {
                var model = new PlotModel { Title = "Cummulative Frequency Polygon" };
                model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title= "Frequency" });
                model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title ="Class Boundaries" });
    
                var cummulativeFQ = new LineSeries();
    
                double[] classBoundaries = new double[numClasses + 1];
    
                double midpointDistance = (lowerLimits[1] - upperLimits[0]) / 2;
    
                classBoundaries[0] = lowerLimits[0] - midpointDistance;
    
                for (int i = 0; i < numClasses; i++)
                {
                    classBoundaries[i + 1] = upperLimits[i] + midpointDistance;
                }
    
                cummulativeFQ.Points.Add(new DataPoint(classBoundaries[0], 0));
    
                for (int i = 0; i< numClasses ; i++)
                {
                    cummulativeFQ.Points.Add(new DataPoint(classBoundaries[i+1], freqs[i]));
                }
    
                model.Series.Add(cummulativeFQ);
    
                //This doesn't update the graph even though I binded it in XAML code
                this.MyModel = model;
            }
            else
            {
                var model = new PlotModel { Title = "Histogram" };
    
                model.Axes.Add(new LinearAxis { Title = "Frequency", Position = AxisPosition.Left });
    
                model.Axes.Add(new CategoryAxis
                {
                    Title = "Class Marks",
                    ItemsSource = classMarksString
    
                });
    
                var histogram = new ColumnSeries();
                model.Series.Add(histogram);
    
                for (int i = 0; i < numClasses; i++)
                {
                    histogram.Items.Add(new ColumnItem(freqs[i]));
                }
    
                //This doesn't update the graph even though I binded it in XAML code
                this.MyModel = model;
    
            }
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Alexei Shcherbakov    7 年前

    快速修复代码

    相反 <oxy:PlotView Model="{Binding MyModel}"/> 使用 <oxy:PlotView x:Name="myPlot"/>

    去除 public PlotModel MyModel { get; private set; } 并在创建模型后直接设置模型。

    myPlot.Model=model;
    

    如果你不知道绑定是如何工作的,请不要使用它。