3

ソリューション ウィンドウドラッグの動的マージン

そのため、ウィンドウが移動するときにポリゴンを移動させようとしています。私は持っています;

    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すべてのポイントの値が明確に示されていても、ポイントは確実に変化しています。PointsListPolygon

Pointsまた、のプロパティをPolygonコードにバインドしようとしました。

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

pointsCollection反対List<Points>ですが同じ結果を使用してみました。Polygonほとんどさわやかではないようです。

4

3 に答える 3

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
}
}
于 2012-07-07T14:44:06.623 に答える
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);
        }

    }
}

}
于 2012-07-06T17:17:39.993 に答える
0

ハンドラーで行うことは、Window_LocationChangedポイントを追加することです。これにより、ポリゴンが増えるのも不思議ではありません。あなたmyPointCollectionはである必要がありObservableCollection、ポイントを追加する前にコレクションをクリアする必要があります。Point( )から継承するクラスを使用できるかどうかも疑問に思いましたが、バインディングを更新できるようにSystem.Windows.Pointxとyをオーバーロードします。NotifyingPropertyChangedそれが機能する場合は、コレクションを変更する必要はありませんが、コレクションのコンテンツを変更する必要があります。

更新後に編集:

更新に問題があるようです。同じコレクションで更新するため、更新は発生しません。コレクション(a )は実装されていないため
、これは完全に正常な動作です。したがって、コレクション(a )をクリアしても、clr'が見る'はすべて同じオブジェクトであるため、変更はなく、更新もありません。PointCollectionCollectionChanged

バインディングは十分であるため、Xaml Polygonオブジェクト自体のポイントコレクションを変更(クリア)しないでください。

  1. PointCollection毎回新しいものを作成し、ポイントを追加して、リストをポリゴンポイントに割り当ててみてください。

  2. または、通知ポイントを作成してポイントを変更してみてください。たぶん、すべてが変更されたことを意味する空の文字列「」でXとYの両方に通知するか、「X」でXに通知し、「Y」でYに通知することができます。

于 2012-06-29T15:09:21.273 に答える