在 XAML 中设置 WPF OxyPlot PlotViews 的样式
Posted
技术标签:
【中文标题】在 XAML 中设置 WPF OxyPlot PlotViews 的样式【英文标题】:Styling WPF OxyPlot PlotViews in XAML 【发布时间】:2017-08-20 02:44:15 【问题描述】:在设置 OxyPlot 绘图视图时,您可以通过各种控件显式定义绘图,或通过绑定到 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>
具有非常薄的视图模型。另一方面,在第二种情况下,我只会有类似
<oxy:PlotView Model="Binding SomePlotModel" />
并在视图模型中构建实际绘图。两种设置各有利弊,但我发现当我事先知道我真正想要绘制的内容时,第一种方法通常效果更好,而第二种方法允许对绘图内容进行动态更改。
我的问题如下:对于第一种情况,我知道如何为所有绘图添加一般样式。例如,如果我想让它们看起来像 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>
致我的ResourceDictionary
。如何在第二种情况下达到相同的效果,即使用oxy:PlotView
?我可以使用<Style TargetType="oxy:PlotView" />
设置一些常规样式属性,但是我将如何设置所有LineSeries
的样式,比如Series
中的Model
中的Model
中的PlotView
?
【问题讨论】:
我也遇到过同样的问题,我能够解决的唯一方法是使用后面的代码来设置 PlotModels 上的属性。它仍然将设计与逻辑分开,但遗憾的是没有使用 XAML 或样式。 @Herman:有没有一种直接的方法可以适用于应用程序中的所有 PlotModel?这是将其设置为样式的好处之一。 我能想到的最好方法是为每种样式创建一个以 PlotModel 作为参数的方法,然后遍历所有绘图模型并为每个 PlotModel 调用该方法。从理论上讲,您可以在一个窗口中找到所有 PlotViews 并提取 PlotModel,但在我的情况下,我的 ViewModel 已经有一个绘图模型数组,因此更简单。 我认为你的问题不够具体。每当使用PlotView
/ PlotModel
/ Plot
时,没有什么能阻止您重新使用 XAML 资源,无论是作为 StaticResource
还是通过代码隐藏中的 Application.Current.Resources["SomeResourceKey"]
。但请记住,可能存在不兼容的类型,例如,Color
和 OxyColor
之间。而且在OxyPlot.Wpf.LinearAxis
和OxyPlot.Axes.LinearAxis
之间......
@RobL 取决于项目的类型;因为这个特别是关于 WPF,我们会做xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf"
。我不知道在Xamarin.Forms
中调用了哪些相关类型,但如果它没有Plot
,我猜你会使用你在Xamarin.Forms
中使用的任何东西。
【参考方案1】:
我没有通过所有的 cmets,但其中一些似乎已经包含解决方案的链接。我有一个示例,我正在使用 MVVM 方法并更改这些设置。它应该有帮助:
在 MainWindow.xaml 中:
<oxy:PlotView Name="TestView" Model="Binding plotModel" Grid.Row="0" Grid.Column="1" />
在我的 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);
然后,当您刷新模型时,如果需要,您可以像这样访问您的轴:
CategoryAxis signalAxis = (CategoryAxis)plotModel.Axes.ElementAt(0);
LinearAxis timeAxis = (LinearAxis)plotModel.Axes.ElementAt(1);
并像这样添加系列:
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);
我并没有完全解决您的问题,但我认为您可以通过这样做访问所有需要的对象/成员。我还简化了我的代码以提高清晰度,我希望这样做时我没有破坏任何东西......
【讨论】:
嗯,是的,我不确定我是否跟随;我遇到的主要问题是应用程序中所有PlotModel
s 的样式;为个人设置样式很简单,最终我选择了@Herman 建议的或多或少的解决方案,创建了一种方法来设置给定PlotModel
的样式,并确保每个相关的都调用该方法。不理想,但它可以完成工作。以上是关于在 XAML 中设置 WPF OxyPlot PlotViews 的样式的主要内容,如果未能解决你的问题,请参考以下文章
WPF - 为啥在 XAML 中设置 Binding BindableObject.Text 时 SetProperty() 不触发 CanExecute?
使用 MvvmCross 时如何在 WPF App.xaml 中设置资源? (MaterialDesignInXamlToolkit)