2014-02-07 29 views
8

如何通過代碼設置WPF畫布兒童的x,y座標? 以下是我的示例代碼。如何通過代碼設置WPF畫布兒童的x,y座標?

Canvas root = new Canvas(); 
double y = 5; 
for (int i=0; i< 10; i++) 
{ 
    Ellipse e = new Ellipse(); 
    e.Height=10; 
    e.Width=10; 
    e.Stroke =Brushes.Black; 

    root.Children.Add(e); 
    y +=10; 
} 

MyRootCanvas = root; 

MyRootCanvas是Canvas類型綁定到WPF UserControl內容的屬性。

+0

@HighCore我需要動態加載控件。 – user2330678

+1

然後使用'ItemsControl'。 WPF的「動態」概念與其他技術真的不同。我強烈建議你學會正確使用WPF,否則由於Visual Tree的複雜性,你會遇到各種各樣的麻煩。 –

+0

@HighCore我正在使用ItemsControl。我的UserControl被加載到一個ItemsControl中。 – user2330678

回答

11

使用Canvas.SetLeftCanvas.SetTop方法組x,y座標爲孩子

for (int I=1; I<= 10; I++) 
{ 
    Ellipse e = new Ellipse(); 
    e.Height=10; 
    e.Width=10; 
    e.Stroke =Brushes.Black; 

    Canvas.SetLeft(e, 10); <-- HERE 
    Canvas.SetTop(e, Y); 

    root.Children.Add(e); 
    Y +=10; 
} 
+0

您確定訂單嗎?在設定其位置之前,不應該添加孩子。無論如何,我做到了這一點,它的作品,因此我會標記你的答案,但請糾正其他用戶。 – user2330678

+2

'Canvas.SetLeft'和'Canvas。SetTop'是畫布的靜態方法。在將項目添加到畫布之前,您可以設置它。在父項中添加項目之前,始終可以設置附加屬性。 –

9

我知道這個問題已經回答了,但什麼HighCore在談論(即不操縱UI元素代碼)不能足夠強調。要做到這一點正常,你應該創建一個類來封裝要顯示的數據:

public class Widget : ViewModelBase 
{ 
    private double _X; 
    public double X 
    { 
     get { return _X;} 
     set { _X = value; RaisePropertyChanged(() => this.X); } 
    } 

    private double _Y; 
    public double Y 
    { 
     get { return _Y;} 
     set { _Y = value; RaisePropertyChanged(() => this.Y); } 
    } 

    private double _Width; 
    public double Width 
    { 
     get { return _Width;} 
     set { _Width = value; RaisePropertyChanged(() => this.Width); } 
    } 

    private double _Height; 
    public double Height 
    { 
     get { return _Height;} 
     set { _Height = value; RaisePropertyChanged(() => this.Height); } 
    } 

    private System.Windows.Media.Color _Color; 
    public System.Windows.Media.Color Color 
    { 
     get { return _Color;} 
     set { _Color = value; RaisePropertyChanged(() => this.Color); } 
    } 
} 

這是一個有點討厭不得不爲每個參數創建這些依賴屬性,我用的是內置的代碼片斷管理器來創建這是我的一個片段,所以我不必每次都輸入整個內容。接下來,您要創建這些數組,並把它們放在一個視圖模型的地方,在哪裏生成橢圓邏輯應該去:

public MyViewModel() 
{ 
    for (int y = 0; y < 10; y++) 
     for (int x = 0; x < 10; x++) 
      this.Items.Add(new Widget { 
       X = x * 20, 
       Y = y * 20, 
       Width = 10, 
       Height = 10, 
       Color = Color.FromArgb(255, (byte)(x * 20), (byte)(y * 20), 0) 
      }); 
} 

你可以這樣設置MyViewModel的實例作爲數據上下文爲包含您的畫布的窗口。所有這一切仍然是鬆散綁定到這個視圖模型的XAML,要渲染的項目清單到畫布上,所以你使用的ItemsControl,並用帆布替換默認的項目小組:

<ItemsControl ItemsSource="{Binding Items}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Ellipse Width="{Binding Width}" Height="{Binding Height}"> 
       <Ellipse.Stroke> 
        <SolidColorBrush Color="{Binding Color}" /> 
       </Ellipse.Stroke> 
      </Ellipse> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
    <ItemsControl.ItemContainerStyle> 
     <Style> 
      <Setter Property="Canvas.Left" Value="{Binding X}" /> 
      <Setter Property="Canvas.Top" Value="{Binding Y}" /> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
</ItemsControl> 

而這裏的結果:

circles

現在你已經把前端數據綁定到您的視圖模型,以便您可以添加/刪除項目或更改個人屬性等及其變化將傳播通過。你也可以單元測試你的邏輯,而不必實際創建視圖控件。