2014-02-22 71 views
0

我發展與WPF和C#這裏我把一個代理在迷宮和GUI內的隨機位置迷宮顯示發現使用搜索算法出口的過程。綁定目標的兩個屬性,以單一來源

我第一次劃分網格的行和列,然後我添加一個矩形上的每個網格/行對,最後我添加一個額外的矩形,以表示我的代理網格。

我要代理的矩形網格中的位置綁定到代表其與Point類位置的代理類屬性。

當我是相當新的,這些技術我看着在網絡上,並與當前的解決方案來:

創建一個新的矩形類至極我打電話ExtendedRectangle並在其中創建一個自定義的DependencyProperty,讓我控制一個Grid.RowProperty和Grid.ColumnProperty通過一個Point。

問題是在我的setter和getter上調試代碼和設置斷點,看起來在使用setValue()方法執行期間沒有達到斷點,但是當我明確修改它的值時調用斷點。此外,我在運行時更改了Agents矩形的位置,並且我看到該值正在更新,但是我的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

首先,你GridPosition依賴屬性聲明是錯誤的。 CLR包裝方法必須請致電GetValueSetValue,他們不應該調用其他任何東西。有關所有詳細信息,請參閱MSDN上的Custom Dependency Properties文章。

然而有沒有必要在所有的ExtendedRectangle類。您可以輕鬆地將常規矩形上的Grid.ColumnGrid.Row屬性綁定到Agent類中的點屬性。此外,爲了簡化您的bindinds,您的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

接下來的事情是,如果您的綁定將會在運行時更新,你必須實現在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屬性的類型,因爲它的XYdouble類型的(你已經意識到這一點)。最好使用一些帶整數XY值的結構。也許寫你自己的。

+0

我放棄了自定義的'DependencyProperty'的想法,實現了你寫的綁定,它現在工作! :D但是我仍然對CLR包裝器方法有疑問,你說它不應該調用其他任何東西tan'Get/SetValue()'...所以如果我想在我的實現中從Getter返回一個'Point' ,我怎麼能這樣做,因爲我需要這兩個值來創建一個? –

+0

請參見[實現[包裝] *部分[定義依賴屬性的清單](http://msdn.microsoft.com/zh-cn/library/ms753358(v = vs.110).aspx#清單)以及MSDN上的[XAML加載和依賴屬性](http://msdn.microsoft.com/zh-cn/library/bb613563(v = vs.110).aspx),以解釋爲什麼CLR包裝器方法不應該調用GetValue和SetValue以外的任何內容。轉換爲其他屬性類型將由[綁定轉換器]完成(http://msdn.microsoft.com/en-us/library/system.windows.data.binding.converter(v = vs.110).aspx) 。 – Clemens

相關問題