所以我正在使用开关和灯泡系统,它们通过电线连接在一起。我应该让开关可以拖动,这样电线也会移动。既然你不能直接在PointCollection中更新积分(我认为它们是我认为的结构?),我已经找到了一种方法,但这看起来非常冗长,我认为必须有更好的方法去做这个。
基本上我检索点,进行操作,清除集合,并添加新点:
Point firstPoint = new Point(firstPointCollection[0].X, firstPointCollection[0].Y + offset.Y);
Point secondPoint = new Point(firstPointCollection[1].X + offset.X, firstPointCollection[1].Y + offset.Y);
Point thirdPoint = new Point(firstPointCollection[2].X + offset.X, firstPointCollection[2].Y + offset.Y);
firstPointCollection.Clear();
firstPointCollection.Add(firstPoint);
firstPointCollection.Add(secondPoint);
firstPointCollection.Add(thirdPoint);
在具有多个线路的系统中,所有线路都由多个点组成,这很快就会变得非常繁琐。这一切都必须在C#中完成,但是如果有更好的方法可以使用某种数据绑定,请告诉我。
答案 0 :(得分:1)
好吧,整个过程可以通过数据绑定完成,所以当你更新灯泡的位置时它会自动更新UI,在这里留下代码示例有点长..
这个演示的结果只是一些带有线条加入它们的圆圈,但是你可以根据需要对它进行模板化。
xaml窗口,它声明了一个项目控件,它将显示灯泡(以及连接它们的线条)
<Window x:Class="points.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:points"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="350" Width="525">
<ItemsControl ItemsSource="{Binding Bulbs}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas HorizontalAlignment="Left" VerticalAlignment="Top">
<Ellipse Fill="Blue" Width="10" Height="10">
<Ellipse.RenderTransform>
<TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
</Ellipse.RenderTransform>
</Ellipse>
<Line X1="{Binding X}" Y1="{Binding Y}" X2="{Binding NextBulb.X}" Y2="{Binding NextBulb.Y}" Stroke="Red">
<Line.RenderTransform>
<TranslateTransform X="5" Y="5"/>
</Line.RenderTransform>
</Line>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Window>
这就是cs,我创造了一个灯泡结构,它保存了灯泡的X和Y位置以及链条中下一个灯泡的参考,我已将所有灯泡放入然后将元素5的Y位置稍微移动一下以显示更新。
using System.Collections.ObjectModel;
using System.Windows;
namespace points
{
public class Bulb : DependencyObject
{
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public static readonly DependencyProperty XProperty =
DependencyProperty.Register("X", typeof(double), typeof(Bulb), new PropertyMetadata(0d));
public double Y
{
get { return (double)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
public static readonly DependencyProperty YProperty =
DependencyProperty.Register("Y", typeof(double), typeof(Bulb), new PropertyMetadata(0d));
public Bulb NextBulb
{
get { return (Bulb)GetValue(NextBulbProperty); }
set { SetValue(NextBulbProperty, value); }
}
public static readonly DependencyProperty NextBulbProperty =
DependencyProperty.Register("NextBulb", typeof(Bulb), typeof(Bulb), new PropertyMetadata(null));
}
public partial class MainWindow : Window
{
public ObservableCollection<Bulb> Bulbs
{
get { return (ObservableCollection<Bulb>)GetValue(BulbsProperty); }
set { SetValue(BulbsProperty, value); }
}
public static readonly DependencyProperty BulbsProperty =
DependencyProperty.Register("Bulbs", typeof(ObservableCollection<Bulb>), typeof(MainWindow), new PropertyMetadata(null));
public MainWindow()
{
Bulbs = new ObservableCollection<Bulb>();
InitializeComponent();
for (int i = 0; i < 10; i++)
{
double x = i * 50;
double y = 25;
Bulbs.Add(new Bulb()
{
X = x,
Y = y,
NextBulb = i > 0 ? Bulbs[i - 1] : null,
});
}
Bulbs[5].Y = 50;
}
}
}
这样做的结果是,以任何方式更改灯泡结构都会更新UI上的灯泡显示,而不必每次都清除并重新创建您的收藏,您甚至可以在属性上运行动画以获得一些非常酷的效果。 / p>
答案 1 :(得分:0)
正如Amnestic指出的那样,即使Point是一个结构体,你也可以通过Offset方法改变它。但是,由于他在使用索引器时使用的是PointCollection而不是Points数组,因此您将获得结构的副本,而不是原始结构。
如果积分在Point []中,你可以使用它:
firstPointCollection[0].Offset(x, y)
但是因为我们使用的是PointCollection,所以你需要设置索引器:
firstPointCollection[0] = firstPointCollection[0].Offset(x, y)
关于结构是否应该是可变的讨论是另外一条鱼。