以编程方式寻址在 xaml 中创建的画布

Posted

技术标签:

【中文标题】以编程方式寻址在 xaml 中创建的画布【英文标题】:programmatically addressing a canvas created in xaml 【发布时间】:2014-09-21 10:17:37 【问题描述】:

我正在使用 MVVM 方法在 WPF 中创建一个应用程序。我对该主题相当陌生,我正在寻找如何实现以下目标的指针:我在 XAML 中创建了一个画布,如下所示:

<canvas name = "myCanvas">
...
</canvas>

我在 XAML 中添加了一个按钮,我想用它在鼠标单击时在现有画布上(以编程方式)绘制一些基本形状(线、矩形等)。由于我使用的是 MVVM 方式,所以按钮的命令必须绑定一个方法,如下:

<Button name="myButton" Command="Binding myMethod, Mode=OneWay">
...
</Button>

我让绑定本身可以正常工作,并且我在 C# 中创建了绘图和形状,但我不明白如何将形状放到用 XAML 创建的画布上。 如何通过我的方法处理在 XAML 中预制的画布?我该怎么做?

编辑:

这里的重点是我想根据数据生成形状以将其可视化。所以,如果我的输入有 3 个类型为 A 的元素,我想创建 3 个矩形并将它们显示在画布上。后来我想让它们可点击并在点击时显示一些关于它们的信息。 MVVM 是我的固定要求。

【问题讨论】:

您能解释一下为什么需要在代码中创建形状吗?视图模型直接处理与 UI 相关的对象有点不正统——通常你应该在 XAML 中定义 UI 相关的东西,或者至少在视图的代码隐藏中。 您的视图模型不了解该视图,因此如果这是视觉“眼睛糖果”,那么您的代码后面的代码是可以接受的 IMO。如果您的形状正在可视化数据,那么我会将受影响的形状元素绑定到该数据。例如,如果您有一个椭圆,其大小基于视图模型中的属性,该属性由命令更新。更多解释会有所帮助。 【参考方案1】:

在您的视图模型中,您应该有一个不使用任何 UI 元素的形状表示:

public class ShapeItem

    public Geometry Geometry  get; set; 
    public Brush Fill  get; set; 
    public Brush Stroke  get; set; 


public class ViewModel

    public ObservableCollection<ShapeItem> ShapeItems  get; set; 

然后您将使用 ItemsControl 和适当的 ItemsPanelItemTemplate 来可视化形状项:

<ItemsControl ItemsSource="Binding ShapeItems">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Path Data="Binding Geometry"
                  Fill="Binding Fill"
                  Stroke="Binding Stroke"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

视图模型可能如下所示进行初始化,并且在执行适当的命令方法时可以类似地添加项目:

var vm = new ViewModel();
vm.ShapeItems = new ObservableCollection<ShapeItem>();
vm.ShapeItems.Add(
    new ShapeItem
    
        Geometry = new EllipseGeometry(new Point(100, 100), 100, 50),
        Fill = Brushes.LightBlue
    );
vm.ShapeItems.Add(
    new ShapeItem
    
        Geometry = new RectangleGeometry(new Rect(150, 100, 200, 100)),
        Fill = Brushes.Azure,
        Stroke = Brushes.Black
    );

DataContext = vm;

【讨论】:

感谢您的宝贵建议!使用你的 sn-ps 我能够实现我想要的。

以上是关于以编程方式寻址在 xaml 中创建的画布的主要内容,如果未能解决你的问题,请参考以下文章

9.ARM寻址方式

MenuItem 以编程方式排序

汇编--寻址方式

30331寻址方式

我们可以以编程方式更改在 iPhone 中创建的快捷方式的图标和名称吗

汇编语言之寻址方式