改变多边形的点数

时间:2012-06-29 14:46:23

标签: c# wpf data-binding polygon point

Dynamic Margin on Window Drag

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

    private void ResetPolygon(Point Point1, Point Point2, Point Point3)
    {
        SpeechPoly.Points.Clear();
        ObservableCollection<Point> myPointCollection = new ObservableCollection<Point>();
        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");
                        }
                    }

但即使Textblock清楚地显示PointsList中所有Polygon的值,多边形仍保持相同的形状。积分肯定在变化。

我还尝试将Points的{​​{1}}属性绑定到我的代码。

Polygon

我也尝试使用<Polygon Name="SpeechPoly" Points="{Binding myPointCollection, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Stroke="Black" StrokeThickness="2" </Polygon> 而不是pointsCollection但结果相同。几乎看起来List<Points>并不令人耳目一新。

3 个答案:

答案 0 :(得分:2)

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

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

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

<Window x:Class="WpfApplication9.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication9"
    Title="MainWindow" Height="350" Width="525" LocationChanged="Window_LocationChanged" >
<Window.Resources>
    <local:MyPointCollectionConverter x:Key="mcolconv" />
</Window.Resources>
<Canvas>
    <Polygon Name="SpeechPoly" Stroke="Black" StrokeThickness="2" 
             Points="{Binding Path=myPointCollection, Converter={StaticResource mcolconv}}" />
</Canvas>

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;

namespace WpfApplication9
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private ObservableCollection<Point> _myPointCollection = new ObservableCollection<Point>();
    public ObservableCollection<Point> 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<Point>)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
}
}

答案 1 :(得分:0)

你在Window_LocationChanged处理程序中所做的就是添加点,所以难怪你最终得到更多的多边形。您的myPointCollection必须是ObservableCollection,您必须在添加积分之前清除收藏。我还想知道你是否可以使用继承自PointSystem.Windows.Point)但是将x和y重载到NotifyingPropertyChanged的类,以便绑定可以更新。如果它有效,则不必再更改集合,而是集合内容。

更新后修改:

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

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

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

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

答案 2 :(得分:0)

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

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

以下示例符合您的要求:

<Window x:Class="WpfApplication9.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" LocationChanged="Window_LocationChanged" >
<Canvas>
    <Polygon Name="SpeechPoly" Stroke="Black" StrokeThickness="2" Points="{Binding Path=myPointCollection}" />
</Canvas>

using System;
using System.Windows;
using System.Windows.Media;

namespace WpfApplication9
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
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);
        }

    }
}

}