如何在知道模型中鼠标位置的情况下评估 x 轴值?
How can I evaluate the x-axis value, knowing the position of the mouse, in the model?
我正在使用 MVVM 模式,通过鼠标行为的附件,我的模型中的 Plot
上有鼠标位置。
我正在为 x 轴使用 DateTimeAxis
,我想从我的 x 位置获取 x 轴值,但我不知道如何进行。
如果我没有使用 MVVM 模式,完成我想要的一个好方法是:
XAML
<oxy:Plot x:Name="TopPlot" MouseMove="TopPlot_MouseMove" >
<oxy:Plot.Axes>
<oxy:DateTimeAxis x:Name="DateAxis" Position="Bottom" />
<oxy:LinearAxis x:Name="ValueAxis" Title="Value" Position="Left"/>
</oxy:Plot.Axes>
</oxy:Plot>
后面的代码:
private void TopPlot_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
var x_axis = this.TopPlot.ActualModel.DefaultXAxis;
var y_axis = this.TopPlot.ActualModel.DefaultYAxis;
var point = OxyPlot.Axes.Axis.InverseTransform(new ScreenPoint(e.GetPosition(TopPlot).X,
e.GetPosition(TopPlot).Y), x_axis, y_axis);
}
我尝试对绘图的 属性 模型进行 OneWayToSource
绑定(这样我就可以在非 MVVM 模型中做一些链接),但是我收到的值是属性 是 null
.
XAML
<oxy:Plot Model="{Binding Path=Plot_Model, Mode=OneWayToSource}" >
<oxy:Plot.Series>
<oxy:LineSeries ItemsSource="{Binding m_Series,
UpdateSourceTrigger=PropertyChanged}"/>
</oxy:Plot.Series>
<oxy:Plot.Axes>
<oxy:DateTimeAxis Position="Bottom"/>
<oxy:LinearAxis Position="Left" Title="Value"/>
</oxy:Plot.Axes>
<i:Interaction.Behaviors>
<mouseMoveMvvm:MouseBehaviour MouseX="{Binding PlotX, Mode=OneWayToSource}"
MouseY="{Binding PlotY, Mode=OneWayToSource}"/>
</i:Interaction.Behaviors>
</oxy:Plot>
我模型中的代码:
private double _plotX;
public double PlotX
{
get { return _plotX; }
set
{
if (value.Equals(_plotX)) return;
_plotX = value;
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(PositionText));
}
}
private double _plotY;
public double PlotY
{
get { return _plotY; }
set
{
if (value.Equals(_plotY)) return;
_plotY = value;
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(PositionText));
}
}
private PlotModel m_model;
public PlotModel Plot_Model
{
set
{
m_model = value;
}
}
public string PositionText
{
get
{
//var x_axis = m_model.DefaultXAxis;
//var y_axis = m_model.DefaultYAxis;
//DataPoint point = Axis.InverseTransform(new ScreenPoint(_plotX, _plotY), x_axis,
// y_axis);
//return string.Format("Pos. X: {0}, /n Pos. Y: {1} ", point.X, point.Y);
return string.Format("Pos. X: {0}, /n Pos. Y: {1} ", _plotX, _plotY);
}
}
有人对如何进行有任何建议吗?
我不知道你从哪里得到 MouseBehavior
,但它可能与 Plot
不兼容。我认为最简单的方法是创建符合您要求的自己的行为,因为您已经有了一个有效的代码隐藏解决方案。如果你把它转化为一种行为,它会是这样的。
public class PlotMousePositionBehaviour : Behavior<Plot>
{
public static readonly DependencyProperty YProperty = DependencyProperty.Register(
nameof(Y), typeof(double), typeof(PlotMousePositionBehaviour));
public static readonly DependencyProperty XProperty = DependencyProperty.Register(
nameof(X), typeof(double), typeof(PlotMousePositionBehaviour));
public double Y
{
get => (double)GetValue(YProperty);
set => SetValue(YProperty, value);
}
public double X
{
get => (double)GetValue(XProperty);
set => SetValue(XProperty, value);
}
protected override void OnAttached()
{
AssociatedObject.MouseMove += OnMouseMove;
}
protected override void OnDetaching()
{
AssociatedObject.MouseMove -= OnMouseMove;
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
var xAxis = AssociatedObject.ActualModel.DefaultXAxis;
var yAxis = AssociatedObject.ActualModel.DefaultYAxis;
var screenPoint = new ScreenPoint(e.GetPosition(AssociatedObject).X, e.GetPosition(AssociatedObject).Y);
var point = OxyPlot.Axes.Axis.InverseTransform(screenPoint, xAxis, yAxis);
X = point.X;
Y = point.Y;
}
}
您可以进一步扩展它,为自定义转换器添加 属性,而不是硬连接点转换。通过这种行为,您可以将 X
和 Y
坐标绑定到您的视图模型。
<oxy:Plot x:Name="TopPlot">
<b:Interaction.Behaviors>
<local:PlotMousePositionBehaviour X="{Binding PlotX}"
Y="{Binding PlotY}"/>
</b:Interaction.Behaviors>
<oxy:Plot.Axes>
<oxy:DateTimeAxis x:Name="DateAxis" Position="Bottom" />
<oxy:LinearAxis x:Name="ValueAxis" Title="Value" Position="Left"/>
</oxy:Plot.Axes>
</oxy:Plot>
关于你的PositionText
,这应该是一个观点的问题。您可以直接在视图中绑定 X
和 Y
并设置文本格式。这是一个示例,为行为分配 x:Name
。
<b:Interaction.Behaviors>
<local:PlotMousePositionBehaviour x:Name="PlotMousePositionBehaviour"/>
</b:Interaction.Behaviors>
通过 ElementName
在 TexBlock
中引用属性(或者使用 StringFormat
)。
<TextBlock>
<Run Text="{Binding X, ElementName=PlotMousePositionBehaviour, StringFormat={}Pos. X: {0}}"/>
<LineBreak/>
<Run Text="{Binding Y, ElementName=PlotMousePositionBehaviour, StringFormat={}Pos. Y: {0}}"/>
</TextBlock>
这样,如果没有在视图模型中使用值,您甚至不需要间接访问视图模型。
我正在使用 MVVM 模式,通过鼠标行为的附件,我的模型中的 Plot
上有鼠标位置。
我正在为 x 轴使用 DateTimeAxis
,我想从我的 x 位置获取 x 轴值,但我不知道如何进行。
如果我没有使用 MVVM 模式,完成我想要的一个好方法是:
XAML
<oxy:Plot x:Name="TopPlot" MouseMove="TopPlot_MouseMove" >
<oxy:Plot.Axes>
<oxy:DateTimeAxis x:Name="DateAxis" Position="Bottom" />
<oxy:LinearAxis x:Name="ValueAxis" Title="Value" Position="Left"/>
</oxy:Plot.Axes>
</oxy:Plot>
后面的代码:
private void TopPlot_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
var x_axis = this.TopPlot.ActualModel.DefaultXAxis;
var y_axis = this.TopPlot.ActualModel.DefaultYAxis;
var point = OxyPlot.Axes.Axis.InverseTransform(new ScreenPoint(e.GetPosition(TopPlot).X,
e.GetPosition(TopPlot).Y), x_axis, y_axis);
}
我尝试对绘图的 属性 模型进行 OneWayToSource
绑定(这样我就可以在非 MVVM 模型中做一些链接),但是我收到的值是属性 是 null
.
XAML
<oxy:Plot Model="{Binding Path=Plot_Model, Mode=OneWayToSource}" >
<oxy:Plot.Series>
<oxy:LineSeries ItemsSource="{Binding m_Series,
UpdateSourceTrigger=PropertyChanged}"/>
</oxy:Plot.Series>
<oxy:Plot.Axes>
<oxy:DateTimeAxis Position="Bottom"/>
<oxy:LinearAxis Position="Left" Title="Value"/>
</oxy:Plot.Axes>
<i:Interaction.Behaviors>
<mouseMoveMvvm:MouseBehaviour MouseX="{Binding PlotX, Mode=OneWayToSource}"
MouseY="{Binding PlotY, Mode=OneWayToSource}"/>
</i:Interaction.Behaviors>
</oxy:Plot>
我模型中的代码:
private double _plotX;
public double PlotX
{
get { return _plotX; }
set
{
if (value.Equals(_plotX)) return;
_plotX = value;
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(PositionText));
}
}
private double _plotY;
public double PlotY
{
get { return _plotY; }
set
{
if (value.Equals(_plotY)) return;
_plotY = value;
NotifyPropertyChanged();
NotifyPropertyChanged(nameof(PositionText));
}
}
private PlotModel m_model;
public PlotModel Plot_Model
{
set
{
m_model = value;
}
}
public string PositionText
{
get
{
//var x_axis = m_model.DefaultXAxis;
//var y_axis = m_model.DefaultYAxis;
//DataPoint point = Axis.InverseTransform(new ScreenPoint(_plotX, _plotY), x_axis,
// y_axis);
//return string.Format("Pos. X: {0}, /n Pos. Y: {1} ", point.X, point.Y);
return string.Format("Pos. X: {0}, /n Pos. Y: {1} ", _plotX, _plotY);
}
}
有人对如何进行有任何建议吗?
我不知道你从哪里得到 MouseBehavior
,但它可能与 Plot
不兼容。我认为最简单的方法是创建符合您要求的自己的行为,因为您已经有了一个有效的代码隐藏解决方案。如果你把它转化为一种行为,它会是这样的。
public class PlotMousePositionBehaviour : Behavior<Plot>
{
public static readonly DependencyProperty YProperty = DependencyProperty.Register(
nameof(Y), typeof(double), typeof(PlotMousePositionBehaviour));
public static readonly DependencyProperty XProperty = DependencyProperty.Register(
nameof(X), typeof(double), typeof(PlotMousePositionBehaviour));
public double Y
{
get => (double)GetValue(YProperty);
set => SetValue(YProperty, value);
}
public double X
{
get => (double)GetValue(XProperty);
set => SetValue(XProperty, value);
}
protected override void OnAttached()
{
AssociatedObject.MouseMove += OnMouseMove;
}
protected override void OnDetaching()
{
AssociatedObject.MouseMove -= OnMouseMove;
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
var xAxis = AssociatedObject.ActualModel.DefaultXAxis;
var yAxis = AssociatedObject.ActualModel.DefaultYAxis;
var screenPoint = new ScreenPoint(e.GetPosition(AssociatedObject).X, e.GetPosition(AssociatedObject).Y);
var point = OxyPlot.Axes.Axis.InverseTransform(screenPoint, xAxis, yAxis);
X = point.X;
Y = point.Y;
}
}
您可以进一步扩展它,为自定义转换器添加 属性,而不是硬连接点转换。通过这种行为,您可以将 X
和 Y
坐标绑定到您的视图模型。
<oxy:Plot x:Name="TopPlot">
<b:Interaction.Behaviors>
<local:PlotMousePositionBehaviour X="{Binding PlotX}"
Y="{Binding PlotY}"/>
</b:Interaction.Behaviors>
<oxy:Plot.Axes>
<oxy:DateTimeAxis x:Name="DateAxis" Position="Bottom" />
<oxy:LinearAxis x:Name="ValueAxis" Title="Value" Position="Left"/>
</oxy:Plot.Axes>
</oxy:Plot>
关于你的PositionText
,这应该是一个观点的问题。您可以直接在视图中绑定 X
和 Y
并设置文本格式。这是一个示例,为行为分配 x:Name
。
<b:Interaction.Behaviors>
<local:PlotMousePositionBehaviour x:Name="PlotMousePositionBehaviour"/>
</b:Interaction.Behaviors>
通过 ElementName
在 TexBlock
中引用属性(或者使用 StringFormat
)。
<TextBlock>
<Run Text="{Binding X, ElementName=PlotMousePositionBehaviour, StringFormat={}Pos. X: {0}}"/>
<LineBreak/>
<Run Text="{Binding Y, ElementName=PlotMousePositionBehaviour, StringFormat={}Pos. Y: {0}}"/>
</TextBlock>
这样,如果没有在视图模型中使用值,您甚至不需要间接访问视图模型。