如何通过代码设置WPF画布子的x,y坐标?

use*_*678 9 .net c# wpf wpf-controls

如何通过代码设置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;
Run Code Online (Sandbox Code Playgroud)

MyRootCanvas是绑定到WPF UserControl内容的Canvas类型的属性.

Roh*_*ats 14

使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • `Canvas.SetLeft`和`Canvas.SetTop`是canvas的静态方法.您可以在将项目实际添加到画布之前进行设置.在父项中添加项之前,始终可以设置附加属性. (2认同)

Mar*_*man 11

我知道这个问题已经得到解答,但是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); }
    }
}
Run Code Online (Sandbox Code Playgroud)

为每个参数创建这些依赖项属性有点烦人,我使用内置的代码片段管理器为我创建一个片段,这样我就不必每次都输入整个内容.接下来你要创建一个这样的数组并将它们放在某个视图模型中,这就是生成省略号的逻辑应该去的地方:

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)
            });
}
Run Code Online (Sandbox Code Playgroud)

然后,您将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>
Run Code Online (Sandbox Code Playgroud)

这是结果:

界

现在,您的前端数据绑定到视图模型,以便您可以添加/删除项目或更改单个属性等,并且更改将传播通过.您还可以对逻辑进行单元测试,而无需实际创建视图控件.