Styling WPF OxyPlot PlotViews in XAML

与世无争的帅哥 提交于 2020-02-01 03:55:10

问题


When setting up an OxyPlot plot view, you can either define the plot explicitly through various controls, or set it up through a binding to a PlotModel.

As such, in the first case, the XAML for a plot of two LineSeries objects could look something like

<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>

with a very thin view-model. On the other hand, in the second case, I would simply have something like

<oxy:PlotView Model="{Binding SomePlotModel}" />

and construct the actual plot in the view-model. There are pros and cons to both setups, but I find that the first approach generally works better when I know beforehand what I actually want to plot, whereas the second approach allows for dynamic changes to the plot contents.

My issue is the following: For the first case I know how to add general styling to all plots. If, for instance, I want them to make them look Seaborn-like, I would just add something like

<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>

to my ResourceDictionary. How can I achieve the same effect in the second case, i.e. using an oxy:PlotView? I can set some of the general styling properties using a <Style TargetType="oxy:PlotView" />, but how would I style, say, all LineSeries contained within a Series within a Model within a PlotView?


回答1:


I didn't get through all the comments but some of them seems to already contain links to the solution. I have an example where I'm using MVVM approach and changing those setting. It should help:

In MainWindow.xaml:

<oxy:PlotView Name="TestView" Model="{Binding plotModel}" Grid.Row="0" Grid.Column="1" />

In my 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);
}

Then when you are refreshing your model, you can access your axis like this if needed:

CategoryAxis signalAxis = (CategoryAxis)plotModel.Axes.ElementAt(0);
LinearAxis timeAxis = (LinearAxis)plotModel.Axes.ElementAt(1);

and add series like this:

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);

I'm not addressing exactly what you asked, but I think you have access to all needed objects/members by doing this. I also simplified my code to improve clarity, I hope I didn't break anything when doing so...



来源:https://stackoverflow.com/questions/43045617/styling-wpf-oxyplot-plotviews-in-xaml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!