【发布时间】:2016-05-29 16:58:15
【问题描述】:
当我尝试使用 WPF 中的 MVVM 模式画线时遇到问题。 我按照这个例子:Drawing line on a canvas in WPF MVVM doesn't work
我遇到的问题是,我想在已经实现的视频控件上画线,我不能将其用作 ItemsPanelTemplate。 所以我的代码目前看起来像这样:
xaml
<ContentControl>
<views:ExtendedMediaElement x:Name="MediaPlayer" Grid.Row="0" ScrubbingEnabled="True" LoadedBehavior="Manual" UnloadedBehavior="Stop"
MediaLength="{Binding MediaLength, Mode=OneWayToSource}"
MediaPosition="{Binding MediaPosition, Mode=TwoWay}"
EndPosition="{Binding EndPosition, Mode=OneWay}"/>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<cal:ActionMessage MethodName="MouseDown">
<cal:Parameter Value="$eventArgs"/>
<cal:Parameter Value="{Binding ElementName=ItemControl}"/>
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</ContentControl>
<ItemsControl x:Name="ItemControl" ItemsSource="{Binding Path=Lines}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line X1="{Binding X1}" Y1="{Binding Y1}" X2="{Binding X2}" Y2="{Binding Y2}" Stroke="{Binding Stroke}" StrokeThickness="{Binding StrokeThickness}"></Line>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
视图模型
private ObservableCollection<Line> _lines;
public ObservableCollection<Line> Lines
{
get { return _lines; }
set
{
if (_lines != value)
{
_lines = value;
NotifyOfPropertyChange("Lines");
}
}
}
public void MouseDown(MouseButtonEventArgs e, System.Windows.Controls.ItemsControl lineArea)
{
System.Windows.Point p = e.GetPosition(lineArea);
if (!isFirstPointSet)
{
firstClickPoint = p;
isFirstPointSet = true;
return;
}
Line l = new Line();
l.X1 = firstClickPoint.X;
l.Y1 = firstClickPoint.Y;
l.X2 = p.X;
l.Y2 = p.Y;
l.Stroke = System.Windows.Media.Brushes.Black;
l.StrokeThickness = 4;
Lines.Add(l);
firstClickPoint = p;
}
现在我画的第一条线总是完美地放置在点击坐标上,但是第二条线在 X 坐标上有一个偏移量。第三条线通常甚至不再可见。
提前感谢您的帮助! 尼可
【问题讨论】:
-
才发现忘记设置ItemsPanel属性。您可以从该链接复制代码并验证它是否解决了问题。查看我的更新答案
-
@kennyzx 我在第二天解决了这个问题,方法是使用 Line 作为参数引发事件并发布事件,以便 .xaml.cs 文件可以处理事件并直接画线在画布上。我也许应该用这个解决方法回答我自己的问题,但我犹豫了,因为我认为它不适用于 MVVM 模式,是吗?
-
纯 MVVM 很难实现并且通常不切实际,所以不要担心代码“破坏”了 MVVM。但是对于这种情况,您的解决方法无法回答您遇到此问题的原因,因此我认为将其作为答案发布是不合适的。