我使用了以下数据模板:
<DataTemplate>
<Grid Width="40" Height="40">
<Ellipse Width="30" Height="30" x:Name="ellipse" />
<TextBlock Text="{Binding Robot.Id}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Line X1="20" X2="40" X2="20" X2="30" x:Name="line" />
</Grid>
</DataTemplate>当DataContext的属性发生变化时,我希望将以下代码应用于该行:
void UpdateHeading(double angle)
{
var center = grid.Width/2;
var radius = ellipse.Width/2;
line.X1 = center + (radius+5)*Math.Sin(angle);
line.Y1 = center + (radius+5)*Math.Cos(angle);
line.X2 = center + (radius-5)*Math.Sin(angle);
line.Y2 = center + (radius-5)*Math.Cos(angle);
}请注意,代码需要访问另外两个元素的大小
添加代码的最佳方式是什么?使用值转换器在这里似乎不合适,因为我需要将一个属性转换为四个属性
发布于 2011-03-27 06:27:52
我决定创造我自己的形状。
XAML用法:
<Grid Width="40" Height="40">
<Ellipse x:Name="ellipse" Width="30" Height="30" />
<TextBlock Text="{Binding Robot.Id}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Controls:HeadingLine BoundingSize="40" ShapeSize="30" Length="10" Angle="{Binding Heading}" Stroke="Black" StrokeThickness="1" />
</Grid>和代码:
public sealed class HeadingLine : Shape
{
// Properties definitions
....
// Code based on http://www.codeproject.com/KB/WPF/wpfarrow.aspx
protected override Geometry DefiningGeometry
{
get
{
var geometry = new StreamGeometry();
using (var context = geometry.Open())
{
InternalDrawArrowGeometry(context);
}
geometry.Freeze();
return geometry;
}
}
private void InternalDrawArrowGeometry(StreamGeometryContext context)
{
var center = BoundingSize / 2;
var radius = ShapeSize / 2;
var offset = Length / 2;
var angle = Math.PI - Angle;
var x1 = center + (radius + offset) * Math.Sin(angle);
var y1 = center + (radius + offset) * Math.Cos(angle);
var x2 = center + (radius - offset) * Math.Sin(angle);
var y2 = center + (radius - offset) * Math.Cos(angle);
context.BeginFigure(new Point(x1, y1), false, false);
context.LineTo(new Point(x2, y2), true, true);
}
}发布于 2011-03-26 03:49:06
还有一个IMultiValueConverter
编辑:您应该有一个带有角度属性的ViewModel,然后可以像下面这样绑定(我只为x1演示过:
<DataTemplate>
<Grid Width="40" Height="40" x:Name="grid">
<Ellipse Width="30" Height="30" x:Name="ellipse" />
<TextBlock Text="{Binding Robot.Id}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Line X2="40" X2="20" X2="30" x:Name="line">
<Line.X1>
<MultiBinding Converter="{StaticResource yourConverter}" ConverterParameter="{yourns:Enum">
<Binding ElementName=grid Path=Width />
<Binding ElementName=ellipse Path=Width />
<Binding Path=Angle />
</MultiBinding>
</Line.X1>
</Line>
</Grid>
</DataTemplate>发布于 2011-03-26 05:21:05
在提供DataContext的类中实现INotifyPropertyChanged,并公开需要更新的所有值的属性。然后只需绑定到这些属性。属性可以计算它们需要的任何值,并且UI将得到更新。
例如:
public class Heading : INotifyPropertyChanged
{
private string name = "";
public string Name { get { return name; } set { name = value; SendPropertyChanged("Name"); } }
public int Radius { get { return GridWidth/2; } }
public double X1 { get { return Center + (Radius + 5) * Math.Sin(Angle); } }
public double X2 { get { return Center + (Radius + 5) * Math.Cos(Angle); } }
public double Y1 { get { return Center + (Radius - 5) * Math.Sin(Angle); } }
public double Y2 { get { return Center + (Radius - 5) * Math.Cos(Angle); } }
public int Center { get { return GridWidth/2; } }
private int gridWidth = 50;
public int GridWidth { get { return gridWidth; } set { gridWidth = value; } }
private double angle;
public double Angle { get { return angle; } set { angle = value; SendPropertyChanged(""); } } //Empty string to notify of all properties
public event PropertyChangedEventHandler PropertyChanged;
void SendPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}然后只需在模板中设置绑定:
<DataTemplate>
<Grid >
<Ellipse Width="{Binding GridWidth}" Height="40" x:Name="ellipse" Fill="Green" />
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Line X1="{Binding X1}" X2="{Binding X2}" Y1="{Binding Y1}" Y2="{Binding Y2}" x:Name="line" Stroke="Black" />
</Grid>
</DataTemplate>希望这能有所帮助。
https://stackoverflow.com/questions/5437386
复制相似问题