|c#|如何从另一个 class 中绘制 wpf?

|c#| how to draw in wpf from another class?

好的,我知道在 wpf 中绘图的唯一方法是在小时候将其设置为网格、面板等后添加形状。在另一个 class 中制作它们 public 之后,我尝试将它们添加到我的网格中,但最终只做了一个无限循环。所以我的问题是如何有效地从 wpf 中的网格上的另一个 class 绘制。

So my question is how do I draw from another class on grid in wpf efficiently.

你不知道。您公开将数据传递给封装网格的 class 的方法,class 将执行验证,如果正确,它将显示它认为合适的数据。这样你就实现了模型与控制器的分离。

Okay so the only way to draw in wpf I know of is by adding your shape after setting it up to grid, panel etc as a child

WPF 完全能够显示可写位图以及 GDI+ 位图。事实上,这比为 GPU 添加多个形状对象以一遍又一遍地处理和渲染要好得多。

你必须以不同的方式思考这个问题。 WPF 旨在与 MVVM 编程风格配合使用。您的网格位于 XAML 代码中的视图需要绑定到包含业务逻辑的 ViewModel 上的属性。这将允许您从另一个 class 更新属性,然后更新绑定到 属性 的视图。

是一篇关于入门的好文章: http://www.codeproject.com/Articles/819294/WPF-MVVM-step-by-step-Basics-to-Advance-Level

如果你正在接触 WPF,我也推荐你购买这本书: Windows Pavel Yosifovich 的演示文稿 4.5 食谱

您的网格应根据 ViewModel 中不断变化的绑定属性进行绘制。 例如,您可以让线条形状根据其绑定的内容在屏幕上移动。您的主窗口将如下所示:

<Window x:Class="Grid_Drawing.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Grid_Drawing"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid x:Name="MainGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
           <Canvas Height="300" Width="300">
            <Line X1="{Binding StartX1}" 
                  X2="{Binding EndX2}" 
                  Y1="{Binding StartY1}" 
                  Y2="{Binding EndY2}" 
                  Stroke="Red"/>
        </Canvas>
    </Grid>
</Window>

然后您可以将 MainWindow 的 DataContext 设置(通常从 App.Xaml.cs)到 ViewModel Class,称为 DrawingViewModel 之类的东西,它继承自 INotifyPropertyChanged(WPF 中最重要的接口)。您的 class 看起来像:

public class DrawingViewModel : INotifyPropertyChanged
{
    private double _startX1;
    private double _endX2;
    private double _startY1;
    private double _endY2;

    // properties

    public double StartX1
    {
        get { return _startX1; }
        set
        {
            if (_startX1 != value)
            {
                _startX1 = value;
                OnPropertyChanged("StartX1");
            }

        }
    }

    public double EndX2
    {
        get { return _endX2; }
        set
        {
            if (_endX2 != value)
            {
                _endX2 = value;
                OnPropertyChanged("EndX2");
            }
        }
    }

    public double StartY1
    {
        get { return _startY1; }
        set
        {
            if (_startY1 != value)
            {
                _startY1 = value;
                OnPropertyChanged("StartY1");
            }
        }
    }

    public double EndY2
    {
        get { return _endY2; }
        set
        {
            if (_endY2 != value)
            {
                _endY2 = value;
                OnPropertyChanged("EndY2");
            }
        }
    }

    // end properties

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

然后,如果您将 DrawingViewModel 作为参考,则可以修改此 class 或另一个 class 的线的起点或终点坐标。希望对您有所帮助。