我正在开发一个带有WPF和C#的迷宫,我将一个代理放在迷宫内的一个随机位置,GUI显示了使用搜索算法找到退出的过程。
我首先在行和列上划分网格,然后在每个网格/行对上添加一个矩形,最后我在代表我的代理的网格中添加一个额外的矩形。
我想将Grid中代理Rectangle的位置绑定到一个Agent类属性,该属性用Point类表示它的位置。
由于我对这些技术还很陌生,所以我在网上看了一下当前的解决方案:
创建一个新的矩形类,我调用ExtendedRectangle并在其中创建一个自定义的DependencyProperty,它通过Point控制Grid.RowProperty和Grid.ColumnProperty。
问题是在我的setter和getter上调试代码和设置断点,似乎在使用setValue()方法执行期间没有达到断点,但是当我明确地修改它的值时它们被调用。此外,我在运行时更改了代理矩形的位置,我看到值正在更新,但我的GUI不是。
我想对这个或更好的方法有所启发。感谢。
这是我在MainWindow.xaml.cs上进行绑定的方法:
public partial class MainWindow : Window
{
Maze maze = new Maze(15, 15);
TimerCallback callback; //
Timer stateTimer; //
public MainWindow()
{
InitializeComponent();
DataContext = maze;
DrawMap(15, 15);
callback = new TimerCallback(Update); //
stateTimer = new Timer(callback, null, 2000, 2000); //
}
public void DrawMap(int ancho, int alto)
{
/********ADD COLUMNS, ROWS AND RECTANGLES CODE WAS HERE*************/
// commented code are my tests
ExtendedRectangle agent = new ExtendedRectangle();
agent.BaseRectangle.Fill = new SolidColorBrush(Colors.LightGreen);
//agent.GridPosition = new Point(5, 5);
//Console.WriteLine(agent.GridPosition.ToString());
//Console.WriteLine(maze.GetAgent().Position.ToString());
agent.SetValue(ExtendedRectangle.GridPositionProperty, maze.GetAgent().Position);
//Console.WriteLine(agent.GridPosition.ToString());
Binding bind = new Binding("Position") { Source = maze.GetAgent() };
bind.Mode = BindingMode.OneWay;
//bind.Converter = new AgentToGridPosition();
agent.SetBinding(ExtendedRectangle.GridPositionProperty, bind);
Mapa.Children.Add(agent.BaseRectangle);
}
public void Update(Object stateInfo) //
{
Random r = new Random();
int x = r.Next(0, 14);
int y = r.Next(0, 14);
Point p = new Point(x, y);
maze.GetAgent().Position = p;
Console.WriteLine("UPDATED POSITION:" + maze.GetAgent().Position.ToString());
}
}
这是我的ExtendedRectangle类:
class ExtendedRectangle
{
private Rectangle baseRectangle;
private Point propertyType;
public ExtendedRectangle()
{
baseRectangle = new Rectangle();
propertyType = new Point();
}
public Rectangle BaseRectangle
{
get
{
return baseRectangle;
}
}
public static readonly DependencyProperty GridPositionProperty = DependencyProperty.Register(
"GridPosition", typeof(Point), typeof(ExtendedRectangle));
public Point GridPosition
{
get
{
propertyType.X = Convert.ToDouble(baseRectangle.GetValue(Grid.ColumnProperty));
propertyType.Y = Convert.ToDouble(baseRectangle.GetValue(Grid.RowProperty));
return propertyType;
}
set
{
propertyType = value;
baseRectangle.SetValue(Grid.ColumnProperty, (int)propertyType.X);
baseRectangle.SetValue(Grid.RowProperty, (int)propertyType.Y);
}
}
public void SetValue(DependencyProperty dp, object value)
{
baseRectangle.SetValue(dp, value);
}
public BindingExpressionBase SetBinding(DependencyProperty dp, BindingBase binding)
{
return baseRectangle.SetBinding(dp, binding);
}
}
答案 0 :(得分:0)
首先,您的GridPosition
依赖项属性声明是错误的。 CLR包装器方法必须调用GetValue和SetValue,并且不应调用其他任何内容。有关所有详细信息,请参阅MSDN上的Custom Dependency Properties文章。
然而,您的ExtendedRectangle
课程根本没有必要。您可以轻松地将常规Rectangle上的Grid.Column
和Grid.Row
属性绑定到Agent
类中的point属性。此外,为了简化绑定,您的Maze
类应该具有Agent
属性而不是GetAgent
方法。
在XAML中它看起来像这样:
<Grid x:Name="grid">
...
<Rectangle Grid.Column="{Binding Agent.Position.X}"
Grid.Row="{Binding Agent.Position.Y}"
Fill="LightGreen"/>
</Grid>
在这样的代码中:
var rectangle = new Rectangle { Fill = Brushes.LightGreen };
rectangle.SetBinding(Grid.ColumnProperty, new Binding("Agent.Position.X"));
rectangle.SetBinding(Grid.RowProperty, new Binding("Agent.Position.Y"));
grid.Children.Add(rectangle);
请注意,通过类Agent
中的Maze
属性,您无需显式设置绑定源,因为Maze
实例已分配给MainWindow的DataContext
1}}。
接下来就是如果你的绑定应该在运行时更新,你必须在Agent
类中实现属性更改通知机制。一种方法是实现INotifyPropertyChanged
接口,如下所示:
class Agent : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Point position;
public Point Position
{
get { return position; }
set
{
position = value;
RaisePropertyChanged("Position");
}
}
protected void RaisePropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
最后,我建议不要将Point
用作Agent.Position
属性的类型,因为其X
和Y
值的类型为double
(你已经意识到这一点)。更好地使用具有整数X
和Y
值的结构。也许自己写一个。