在XAML中设置WPF OxyPlot PlotViews的样式

fug*_*ede 6 .net c# wpf xaml oxyplot

设置OxyPlot绘图视图时,您可以通过各种控件显式定义绘图,也可以通过绑定到a来设置PlotModel.

因此,在第一种情况下,两个LineSeries对象的绘图的XAML 可能看起来像

<oxy:Plot Title="Some plot">
    <oxy:Plot.Axes>
        <oxy:LinearAxis Position="Left" />
        <oxy:LinearAxis Position="Bottom" />
    </oxy:Plot.Axes>
    <oxy:Plot.Series>
        <oxy:LineSeries ItemsSource="{Binding ActualSeriesData1}" DataFieldX="X" DataFieldY="Y"/>
        <oxy:LineSeries ItemsSource="{Binding ActualSeriesData2}" DataFieldX="X" DataFieldY="Y"/>
    </oxy:Plot.Series>
</oxy:Plot>
Run Code Online (Sandbox Code Playgroud)

具有非常薄的视图模型.另一方面,在第二种情况下,我只会有类似的东西

<oxy:PlotView Model="{Binding SomePlotModel}" />
Run Code Online (Sandbox Code Playgroud)

并在视图模型中构建实际的图.两种设置都有利有弊,但我发现第一种方法通常在我事先知道我想要绘制的内容时效果更好,而第二种方法允许对绘图内容进行动态更改.

我的问题如下:对于第一种情况,我知道如何为所有图添加一般样式.例如,如果我想让它们看起来像Seaborn,我会添加类似的东西

<x:Array Type="Color" x:Key="SeabornColors">
    <Color>#4c72b0</Color>
    <Color>#55a868</Color>
    <Color>#c44e52</Color>
    <Color>#8172b2</Color>
    <Color>#ccb974</Color>
    <Color>#64b5cd</Color>
</x:Array>
<Style TargetType="oxy:Plot">
    <Setter Property="PlotAreaBackground" Value="#EBEBF2" />
    <Setter Property="PlotAreaBorderThickness" Value="0" />
    <Setter Property="TitleFont" Value="Segoe UI" />
    <Setter Property="TitleFontWeight" Value="Normal" />
    <Setter Property="DefaultColors" Value="{StaticResource SeabornColors}"/>
</Style>
<Style TargetType="oxy:LinearAxis">
    <Setter Property="TicklineColor" Value="White" />
    <Setter Property="MajorGridlineColor" Value="White" />
    <Setter Property="MinorGridlineColor" Value="White" />
    <Setter Property="ExtraGridlineColor" Value="White" />
    <Setter Property="AxislineColor" Value="White" />
    <Setter Property="TitleColor" Value="Black" />
    <Setter Property="TextColor" Value="Black" />
    <Setter Property="Font" Value="Segoe UI" />
    <Setter Property="TitleFont" Value="Segoe UI" />
    <Setter Property="TickStyle" Value="None" />
    <Setter Property="MajorGridlineStyle" Value="Solid" />
</Style>
Run Code Online (Sandbox Code Playgroud)

我的ResourceDictionary.如何在第二种情况下实现相同的效果,即使用oxy:PlotView?我可以设置一些使用一般的样式属性的<Style TargetType="oxy:PlotView" />,但如何将我的风格,比方说,所有LineSeries包含在一个SeriesModelPlotView

小智 1

我没有阅读所有评论,但其中一些似乎已经包含解决方案的链接。我有一个使用 MVVM 方法并更改这些设置的示例。它应该有帮助:

在MainWindow.xaml中:

<oxy:PlotView Name="TestView" Model="{Binding plotModel}" Grid.Row="0" Grid.Column="1" />
Run Code Online (Sandbox Code Playgroud)

在我的 MainWindowViewModel.cs 中:

private PlotModel m_plotModel;
public PlotModel plotModel
{
    get { return m_plotModel; }
    set => SetAndRaisePropertyChanged(ref m_plotModel, value);
}

public UserControlOscilloViewModel()
{
    var signalAxis = new CategoryAxis()
    {
        Position = AxisPosition.Left,
        Minimum = 0,
        MinimumMinorStep = 1,
        AbsoluteMinimum = 0,
        TicklineColor = OxyColors.Transparent,
    };
    var timeAxis = new LinearAxis()
    {
        Position = AxisPosition.Bottom,
        Minimum = 0,
        MinimumMajorStep = 1,
        AbsoluteMinimum = 0,
    };

    plotModel = new PlotModel();            
    plotModel.Axes.Add(signalAxis);
    plotModel.Axes.Add(timeAxis);
}
Run Code Online (Sandbox Code Playgroud)

然后,当您刷新模型时,如果需要,您可以像这样访问轴:

CategoryAxis signalAxis = (CategoryAxis)plotModel.Axes.ElementAt(0);
LinearAxis timeAxis = (LinearAxis)plotModel.Axes.ElementAt(1);
Run Code Online (Sandbox Code Playgroud)

并添加这样的系列:

var series = new LineSeries
{
    Color = OxyColors.SeaShell,
    LineStyle = LineStyle.Dash
};
foreach (DataPoint p in ListOfPoints)
{
    series.Points.Add(p);
}
plotModel.Series.Add(series);
plotModel.InvalidatePlot(true);
Run Code Online (Sandbox Code Playgroud)

我没有完全解决您所要求的问题,但我认为您可以通过这样做来访问所有需要的对象/成员。我还简化了我的代码以提高清晰度,我希望这样做时没有破坏任何东西......