【问题标题】:WPF MVVM: Dynamic drawing of a shape from a xaml fileWPF MVVM:从 xaml 文件动态绘制形状
【发布时间】:2014-07-18 09:41:18
【问题描述】:

我有一个从 SVG 文件转换而来的 XAML 文件,看起来像这样(它代表一个音符):

    <?xml version="1.0" encoding="UTF-8"?>
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
    <Canvas Name="Layer_1" Width="50" Height="50" Canvas.Left="0" Canvas.Top="0">
        <Canvas.RenderTransform><TranslateTransform X="0" Y="0"/>
        </Canvas.RenderTransform><Canvas.Resources/>
        <!--Unknown tag: metadata--><!--Unknown tag: sodipodi:namedview-->
            <Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path2995" Fill="#FFAA0000">
                <Path.Data>
                    <PathGeometry Figures="M39.967 23.133c-0.211 0.189-0.523 0.199-0.748 0.028l-7.443-5.664l-3.526 21.095c-0.013 0.08-0.042 0.153-0.083 0.219  c-0.707 3.024-4.566 5.278-9.104 5.278c-5.087 0-9.226-2.817-9.226-6.28s4.138-6.281 9.226-6.281c2.089 0 4.075 0.466 5.689 1.324  l4.664-26.453c0.042-0.242 0.231-0.434 0.475-0.479c0.237-0.041 0.485 0.068 0.611 0.28l9.581 16.192  C40.227 22.637 40.178 22.945 39.967 23.133z" FillRule="NonZero"/>
                </Path.Data>
            </Path>
        </Canvas>
</Viewbox>

虽然我对 WPF 和数据绑定比较陌生,但我正在尝试坚持 MVVM 设计模式。我想在这里实现的是使用绑定到按钮的命令(例如)在画布上动态绘制此形状。有没有办法绑定 Path.Data/PathGeometry/Figures 假设我将“M39.967 ...”作为字符串存储在某处(无需担心文件阅读器)?

为了学习动态绘图,我一直在玩这些示例: How do you animate a line on a canvas in C#?

How to create and connect custom user buttons/controls with lines using windows forms

我不知道如何动态绘制一个像上面那样的自定义形状,它可以由用户从文件中导入。请帮忙!

【问题讨论】:

    标签: c# wpf xaml mvvm svg


    【解决方案1】:

    在绑定过程中,一个有效的Path Geometry 字符串确实会自动转换为Geometry

    因此,您可以创建如下所示的 ViewModel(当然,还为所有相关属性实现 INotifyPropertyChanged):

    public class ViewModel
    {
        public string Geometry { get; set; }
    }
    

    通过从文件中读取Geometry 属性以某种方式对其进行初始化,并像这样绑定到它:

    <Path Fill="Black" Data="{Binding Geometry}"/>
    

    使用您的示例几何体进行测试,如下所示:

    DataContext = new ViewModel
    {
        Geometry = "M39.967 23.133c-0.211 0.189-0.523 0.199-0.748 0.028l-7.443-5.664l-3.526 21.095c-0.013 0.08-0.042 0.153-0.083 0.219  c-0.707 3.024-4.566 5.278-9.104 5.278c-5.087 0-9.226-2.817-9.226-6.28s4.138-6.281 9.226-6.281c2.089 0 4.075 0.466 5.689 1.324  l4.664-26.453c0.042-0.242 0.231-0.434 0.475-0.479c0.237-0.041 0.485 0.068 0.611 0.28l9.581 16.192  C40.227 22.637 40.178 22.945 39.967 23.133z"
    };
    

    【讨论】:

      【解决方案2】:

      你可以使用XamlReader从文件中加载一个xaml

      例子

              using (FileStream fs = new FileStream(myFile, FileAccess.Read))
              {
                  Viewbox viewBox = (Viewbox)XamlReader.Load(fs);
                  this.Content = viewBox; //this is a window here
              }
      

      上面的例子从给定的文件中加载了一个Viewbox,并将其设置为窗口的内容,这反过来又会在窗口中显示文件的内容

      您可以根据需要调整代码。如果你需要从一个字符串中加载,你可以像这样使用它

              Viewbox viewBox = (Viewbox)XamlReader.Parse(xamlString);
              this.Content = viewBox;
      

      在上面的示例中,ViewBox 是根据您在问题中给出的 xaml 使用的,它也可能会根据您的需要而改变。

      【讨论】:

      • 感谢您提供这段代码,它可能很有用:)
      • 是的,这将帮助您将存储/导出的数字加载到 xaml 文件中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2017-01-14
      • 2013-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多