在 WPF 中绘制和删除形状
在 GDI+/WinForms 中,我可以在 Click() 事件中执行此操作并使用图形对象:
In GDI+/WinForms, I could do this in the Click() event and using the graphics Object:
AddPoint(p); //Add Point contains some code to make sure there is only 3 dots
foreach (Point p in PointList) {
DrawRectangle(p);
}
Invalidate();
如果我在 WPF 中尝试类似的东西,它不会清理我创建的点(我猜是因为 WPF 的工作原理).这意味着如果我检查以确保一次只有三个点,然后弹出最旧的点为新点腾出空间,绘制的矩形将仍然存在.
If I try something similar in WPF, it won't cleanup the dots I created (I'm guessing because of how WPF works). What this means is if I check to make sure there is only three dots at a time, and pop off the oldest point to make room for the new one, the rectangle drawn would be still there.
所以问题是,我怎样才能在 WPF 中创建一些允许我
So the question is, how can I create something in WPF that allows me to
- 在一个点画一个矩形
- 在超过 3 个后从 WPF 画布中删除矩形/点
您正在以 WinForms 的方式处理 WPF.不要那样做.这就像用 C++ 编写 VB 代码.只能以泪水收场.
You're doing WPF the WinForms way. Don't do that. It's like writing VB code in C++. It can only end in tears.
要以 WPF 方式执行此操作,请使用数据绑定和视图模型类来执行一次不超过 3 个"的逻辑.然后,对于 UI,只需绑定到视图模型中的 PointList.
To do this the WPF way, use databinding and a view model class to do the logic of "no more than 3 at a time." Then, for the UI, just bind to the PointList in your view model.
这是我的 XAML 应该是什么样子.注意我只是使用 ItemsControl 和 Canvas,然后将 ItemsSource 绑定到 PointList:
Here's what my XAML should look like. Notice I'm just using an ItemsControl and a Canvas, then binding the ItemsSource to PointList:
<Window x:Class="WpfTester.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<ItemsControl ItemsSource="{Binding Path=PointList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Fill="Red" Width="25" Height="25" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Path=X}" />
<Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Window>
然后我们只需要创建PointList.我们将使用普通的 WPF 手段:一个视图模型类来保存点列表:
Then we just need to create the PointList. We'll use the normal WPF means: a view model class to hold the point list:
class MainViewModel
{
public MainViewModel()
{
PointList = new ObservableCollection<Point>();
// Some example data:
AddPoint(new Point(10, 10));
AddPoint(new Point(200, 200));
AddPoint(new Point(500, 500));
}
public ObservableCollection<Point> PointList { get; private set; }
public void AddPoint(Point p)
{
// 3 at most, please!
if (PointList.Count == 3)
{
PointList.RemoveAt(0);
}
PointList.Add(p);
}
}
一块奶酪,是吗?所以最后一部分只是告诉 XAML 加载您的视图模型.在 XAML 的代码隐藏中,将 DataContext 设置为您的视图模型:
Piece of cheese, yeah? So the final part is just telling the XAML to load your view model. Inside the the code-behind for your XAML, set the DataContext to your view model:
// Inside MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
// Add this line:
this.DataContext = new MainViewModel();
}
既然您已经准备好了,您只需调用 viewModel.AddPoint 或 viewModel.PointList.Remove 即可在代码中的任何位置添加/删除矩形,UI 将自动更新以反映更改.
Now that you've got that in place, you can add/remove rectangles anywhere in your code simply by calling viewModel.AddPoint or viewModel.PointList.Remove, and the UI will automatically update to reflect the changes.