2013-10-16 43 views
0

我想創建自己的用戶控件(我們稱之爲「RectAtCoordinates」),這將同樣到畫布,但它應該:用戶控件與的ObservableCollection作爲DependencyProperty的

-store的集合(X,Y)的整數座標

- 在每個(x,y)對的畫布上繪製矩形(具有任意選擇的大小和填充)。 (x,y)指定矩形的位置。

首先,我創建了簡單的座標類

class Coordinates : DependencyObject 
    { 
     public static readonly DependencyProperty XProperty = 
      DependencyProperty.Register("X", typeof(int), typeof(Coordinates)); 

     public static readonly DependencyProperty YProperty = 
      DependencyProperty.Register("Y", typeof(int), typeof(Coordinates)); 

     public int X 
     { 
      get { return (int)GetValue(XProperty); } 
      set { SetValue(XProperty, value); } 
     } 

     public int Y 
     { 
      get { return (int)GetValue(YProperty); } 
      set { SetValue(YProperty, value); } 
     } 

     public Coordinates(int x, int y) 
     { 
      this.X = x; 
      this.Y = y; 
     } 
    } 

這裏是我的RectAtCoordinates用戶控件(的.xaml):

<UserControl x:Class="RectAtPoint.RectAtCoordinates" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <ItemsControl ItemsSource="{Binding Path=Coos, Mode=OneWay}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas Width="300" Height="300" Background="White"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Rectangle Fill="Black" Width="50" Height="50"/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     <ItemsControl.ItemContainerStyle> 
      <Style> 
       <Setter Property="Canvas.Left" Value="{Binding Path=X}" /> 
       <Setter Property="Canvas.Top" Value="{Binding Path=Y}" /> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
    </ItemsControl> 
</UserControl> 

背後RectAtCoordinates終於代碼:

public partial class RectAtCoordinates : UserControl 
    { 
     public static readonly DependencyProperty CoosProperty = 
      DependencyProperty.Register("Coos", typeof(Coordinates), typeof(RectAtCoordinates)); 

     private ObservableCollection<Coordinates> Coos 
     { 
      get { return (ObservableCollection<Coordinates>)GetValue(CoosProperty); } 
      set { SetValue(CoosProperty, value); } 
     } 

     public RectAtCoordinates() 
     { 
      InitializeComponent(); 
      Coos = new ObservableCollection<Coordinates>(); 
     } 

     public void AddRectangleAtPosition(int x, int y) 
     { 
      Coos.Add(new Coordinates(x, y)); 
     } 
    } 

但是,建立我的項目後,它崩潰。我得到CLR20r3的問題。經進一步檢查,我改變了RectAtCoordinates構造爲:

public RectAtCoordinates() 
     { 
      InitializeComponent(); 
      try 
      { 
       Coos = new ObservableCollection<Coordinates>(); 
      } 
      catch (Exception e) 
      { 
       MessageBox.Show(e.ToString()); 
      } 
     } 

而得到這個錯誤:

System.ArgumentException: 'System.Collections.ObjectModel.ObservableCollection`1[RectAtPoint.Coordinates]' is not a valid value for property 'Coos'.

at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)

at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)

at RectAtPoint.RectAtCoordinates.set_Coos(ObservableCollection`1 value) in c:...\RectAtCoordinates.xaml.cs:line 28

at RectAtPoint.RectAtCoordinates..ctor() in c:...\RectAtCoordinates.xaml.cs:line 36

我新手考慮WPF,綁定和依賴項屬性,所以,請考慮到我可能會犯一些基本的錯誤。我發現了很多類似的問題,但我無法完全理解解決方案,因此無法正確應用它們。

+1

我認爲你需要聲明每個dp的默認值。 http://msdn.microsoft.com/en-us/library/ms752914.aspx。在Visual Studio中,在您的類中輸入propdp並按Tab 2次。這是依賴項屬性的片段。 – iulian3000

回答

3

我覺得你的問題是在這裏:

public static readonly DependencyProperty CoosProperty = 
      DependencyProperty.Register("Coos", typeof(Coordinates), typeof(RectAtCoordinates)); 

是應該是:

public static readonly DependencyProperty CoosProperty = 
      DependencyProperty.Register("Coos", typeof(ObservableCollection<Coordinates>), typeof(RectAtCoordinates)); 

試試看吧:)

===編輯===對於座標。

我認爲你可以這樣做:

 public void AddRectangleAtPosition(int x, int y) 
      { 
       Coos.Add(new Coordinates(x, y)); 
if (PropertyChanged != null) 
         { 
          PropertyChanged(this, new PropertyChangedEventArgs("Coos")); 
         } 
      } 

那麼你的類應該有:

public partial class RectAtCoordinates : UserControl, INotifyPropertyChanged 

之後,你可以有一個區域像我平時都在NotifyPropertyChanged就象這樣:

#region notifypropertychanged region 

public event PropertyChangedEventHandler PropertyChanged; 

protected virtual void OnPropertyChanged(string propertyName) 
{ 
    PropertyChangedEventHandler handler = PropertyChanged; 
    if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
} 
protected bool SetField<T>(ref T field, T value, string propertyName) 
{ 
    if (EqualityComparer<T>.Default.Equals(field, value)) return false; 
    field = value; 
    OnPropertyChanged(propertyName); 
    return true; 
} 

#endregion 

}

試試:)

+0

就是這樣!你有一隻鷹的眼睛。現在的問題是,向集合添加新的座標不會產生所需的效果(畫布仍然是空的)。不過,我相信這是因爲我應該支持Coos的CollectionChanged Event,對嗎? – browning0

+0

@ browning0我編輯了我的答案。試試看:P – sexta13

+0

嗯,它不起作用......我複製粘貼你的答案,沒有任何反應。 SetField方法的任務是什麼?它似乎沒有被稱爲任何地方。 PropertyChanged似乎通過不斷null,即使我添加新的座標。最後:我讀過這個主題:[鏈接](http://stackoverflow.com/questions/594610/inotifypropertychanged-not-working-on-observablecollection-property),「沒有理由實現INotifyProperty更改爲DependencyProperties。 「但是,我不確定是否能正確理解此答案的上下文...... – browning0

-3

我終於找到了一個解決方案:數據上下文沒有正確設置。 我不得不添加

this.DataContext = this; 

到用戶控件的構造函數或添加:

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

到用戶控件的XAML定義。

+0

將usercontrol datacontext設置爲THIS或{Binding RelativeSource = {RelativeSource Self}}顯然是錯誤的,因爲它會導致綁定對象在相對簡單的情況下。始終綁定到您的usercontrol內的根元素上的DataContext =「{Binding RelativeSource = {RelativeSource FindAncestor, AncestorType = {x:Type YOURTYPE}}}」。這也解釋了所有的downvotes – sam

相關問題