改变多边形的点数

解决方案 窗口拖动的动态余量

所以我试图让我的多边形在窗口移动时移动。 我有;

private void ResetPolygon(Point Point1, Point Point2, Point Point3) { SpeechPoly.Points.Clear(); ObservableCollection myPointCollection = new ObservableCollection(); myPointCollection.Add(Point3); myPointCollection.Add(Point2); myPointCollection.Add(Point1); foreach (Point p in myPointCollection) { SpeechPoly.Points.Add(p); } } private void Window_LocationChanged(object sender, EventArgs e) { if (this.IsLoaded) { Point Point1 = new Point(newPoint3); Point Point2 = new Point(newPoint2); Point Point3 = new Point(newPoint1); ResetPolygon(newPoint1, newPoint2, newPoint3); //Write out the values of both the list and the polygon to screen! txtBlock.Text = newPoint1.X.ToString("N2") + ", " + newPoint1.Y.ToString("N2") + "\n" + newPoint2.X.ToString("N2") + ", " + newPoint2.Y.ToString("N2") + "\n" + newPoint3.X.ToString("N2") + ", " + newPoint3.Y.ToString("N2"); txtBlock.Text += "\n" + SpeechPoly.Points[0].X.ToString("N2") + ", " + SpeechPoly.Points[0].Y.ToString("N2") + "\n" + SpeechPoly.Points[1].X.ToString("N2") + ", " + SpeechPoly.Points[1].Y.ToString("N2") + "\n" + SpeechPoly.Points[2].X.ToString("N2") + ", "+ SpeechPoly.Points[2].Y.ToString("N2"); } } 

但是无论如何,Polygon都保持相同的形状,即使Textblock清楚地显示List中所有Points的值,而Polygon的点肯定会发生变化。

我还尝试将PolygonPoints属性绑定到我的代码。

 <Polygon Name="SpeechPoly" Points="{Binding myPointCollection, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Stroke="Black" StrokeThickness="2"  

我也尝试使用pointsCollection而不是List但结果相同。 几乎看起来Polygon并不令人耳目一新。

我对之前给出的答案并不满意,因为它毕竟是一种解决方法。

我找到了一个更好的解决方案,不需要重置数据集。

因此,来自XAML的绑定被定向到具有INCC的属性,但是数据本身被转换为用于绘制时要使用的多边形的点。

        

 using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; using System.Windows.Data; using System.Windows.Media; namespace WpfApplication9 { ///  /// Interaction logic for MainWindow.xaml ///  public partial class MainWindow : Window, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private ObservableCollection _myPointCollection = new ObservableCollection(); public ObservableCollection myPointCollection { get { return _myPointCollection; } } public MainWindow() { myPointCollection.Add(new Point(100, 50)); myPointCollection.Add(new Point(150, 100)); myPointCollection.Add(new Point(50, 100)); InitializeComponent(); DataContext = this; } private void ResetPolygon(Point Point1, Point Point2, Point Point3) { myPointCollection.Clear(); myPointCollection.Add(Point1); myPointCollection.Add(Point2); myPointCollection.Add(Point3); if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("myPointCollection")); } private void Window_LocationChanged(object sender, EventArgs e) { if (this.IsLoaded) { Random rnd = new Random(); Point Point1 = new Point(rnd.Next(50, 200), rnd.Next(50, 200)); Point Point2 = new Point(rnd.Next(50, 200), rnd.Next(50, 200)); Point Point3 = new Point(rnd.Next(50, 200), rnd.Next(50, 200)); ResetPolygon(Point1, Point2, Point3); } } } public class MyPointCollectionConverter : IValueConverter { #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { var regPtsColl = new PointCollection(); //regular points collection. var obsPtsColl = (ObservableCollection)value; //observable which is used to raise INCC event. foreach (var point in obsPtsColl) regPtsColl.Add(point); return regPtsColl; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return null; } #endregion } } 

PointsCollection不使用INotifyCollectionChanged ..
所以约束永远不会知道某事已经改变了。

你可以通过刷新绑定来解决这个问题。

这是一个做你要求的例子:

     

 using System; using System.Windows; using System.Windows.Media; namespace WpfApplication9 { ///  /// Interaction logic for MainWindow.xaml ///  public partial class MainWindow : Window { public PointCollection myPointCollection { get; set; } public MainWindow() { myPointCollection = new PointCollection { new Point(100, 50), new Point(150, 100), new Point(50, 100) }; InitializeComponent(); DataContext = this; } private void ResetPolygon(Point Point1, Point Point2, Point Point3) { myPointCollection[0] = Point1; myPointCollection[1] = Point2; myPointCollection[2] = Point3; DataContext = null; DataContext = this; } private void Window_LocationChanged(object sender, EventArgs e) { if (this.IsLoaded) { Random rnd = new Random(); Point Point1 = new Point(rnd.Next(50, 200), rnd.Next(50, 200)); Point Point2 = new Point(rnd.Next(50, 200), rnd.Next(50, 200)); Point Point3 = new Point(rnd.Next(50, 200), rnd.Next(50, 200)); ResetPolygon(Point1, Point2, Point3); } } } } 

那么你在Window_LocationChanged处理程序中做的是添加点,所以难怪你最终得到更多的多边形。 您的myPointCollection必须是ObservableCollection ,您必须在添加点之前清除该集合。 我还想知道你是否可以使用从Pointinheritance的类( System.Windows.Point ),但是将x和y重载到NotifyingPropertyChanged它们,以便绑定可以更新。 如果可行,则不必再更改Collection,而是更改Collection内容。

更新后编辑:

看起来问题出现在您的更新中:因为您使用相同的Collection更新它,所以不会发生更新。
这是完全正常的行为,因为Collection(一个PointCollection )没有实现CollectionChanged ,所以即使你清除它,clr’看到’的所有东西都是同一个对象,所以没有变化,因此没有更新。

您不应修改(清除)Xaml Polygon对象本身的点集合,因为绑定就足够了。

  1. 尝试每次创建一个新的PointCollection ,添加点,并将列表分配给多边形点。

  2. 或尝试制作通知点并更改积分。 也许你可以用空字符串“”通知X和Y,这意味着一切都改变了,或者用“X”通知X,用“Y”通知Y.