改变多边形的点数
解决方案 窗口拖动的动态余量
所以我试图让我的多边形在窗口移动时移动。 我有;
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
的点肯定会发生变化。
我还尝试将Polygon
的Points
属性绑定到我的代码。
<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
,您必须在添加点之前清除该集合。 我还想知道你是否可以使用从Point
inheritance的类( System.Windows.Point
),但是将x和y重载到NotifyingPropertyChanged
它们,以便绑定可以更新。 如果可行,则不必再更改Collection,而是更改Collection内容。
更新后编辑:
看起来问题出现在您的更新中:因为您使用相同的Collection更新它,所以不会发生更新。
这是完全正常的行为,因为Collection(一个PointCollection
)没有实现CollectionChanged
,所以即使你清除它,clr’看到’的所有东西都是同一个对象,所以没有变化,因此没有更新。
您不应修改(清除)Xaml Polygon对象本身的点集合,因为绑定就足够了。
-
尝试每次创建一个新的
PointCollection
,添加点,并将列表分配给多边形点。 -
或尝试制作通知点并更改积分。 也许你可以用空字符串“”通知X和Y,这意味着一切都改变了,或者用“X”通知X,用“Y”通知Y.