C# 按照MVVM模式将WPF画布保存为图像

C# 按照MVVM模式将WPF画布保存为图像,c#,wpf,mvvm,icommand,C#,Wpf,Mvvm,Icommand,我有一个画布,例如与使用ItemsControl的画布类似或许多其他画布 现在我想要一个按钮,它应该绑定到一个ICommand。此命令应调用可保存图像的ViewModel类的方法。 保存方法很清楚,但是如何按照MVVM模式进行绑定?如果不想引用ViewModel中的UI元素,可以使用附加的行为: internal static class Behaviours { public static readonly DependencyProperty SaveCanvasProperty =

我有一个画布,例如与使用
ItemsControl
的画布类似或许多其他画布

现在我想要一个按钮,它应该绑定到一个ICommand。此命令应调用可保存图像的ViewModel类的方法。
保存方法很清楚,但是如何按照MVVM模式进行绑定?

如果不想引用ViewModel中的UI元素,可以使用附加的行为:

internal static class Behaviours
{
    public static readonly DependencyProperty SaveCanvasProperty =
        DependencyProperty.RegisterAttached("SaveCanvas", typeof(bool), typeof(Behaviours),
                                            new UIPropertyMetadata(false, OnSaveCanvas));

    public static void SetSaveCanvas(DependencyObject obj, bool value)
    {
        obj.SetValue(SaveCanvasProperty, value);
    }

    public static bool GetSaveCanvas(DependencyObject obj)
    {
        return (bool)obj.GetValue(SaveCanvasProperty);
    }

    private static void OnSaveCanvas(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            // Save code.....
        }
    }
}
<UserControl.Style>
    <Style>
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsSaveCanvas}" Value="True">
                <Setter Property="wpfApplication1:Behaviours.SaveCanvas" Value="True"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsSaveCanvas}" Value="False">
                <Setter Property="wpfApplication1:Behaviours.SaveCanvas" Value="False"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Style>
然后,在ViewModel中,您可以使用命令设置属性,也可以在ViewModel上设置属性:

    public ICommand SaveCanvasCommand
    {
        get
        {
            if (_saveCanvasCommand == null)
                _saveCanvasCommand = new RelayCommand(() => { IsSaveCanvas = true; });

            return _saveCanvasCommand;
        }
    }
以及绑定到视图的属性:

    public bool IsSaveCanvas
    {
        get { return _isSaveCanvas; }
        set
        {
            _isSaveCanvas = value;
            RaisePropertyChanged("IsSaveCanvas");
        }
    }
然后将其连接到Xaml中,如下所示:

控件上添加一个
触发器
,将ViewModel属性的值绑定到附加的行为:

internal static class Behaviours
{
    public static readonly DependencyProperty SaveCanvasProperty =
        DependencyProperty.RegisterAttached("SaveCanvas", typeof(bool), typeof(Behaviours),
                                            new UIPropertyMetadata(false, OnSaveCanvas));

    public static void SetSaveCanvas(DependencyObject obj, bool value)
    {
        obj.SetValue(SaveCanvasProperty, value);
    }

    public static bool GetSaveCanvas(DependencyObject obj)
    {
        return (bool)obj.GetValue(SaveCanvasProperty);
    }

    private static void OnSaveCanvas(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            // Save code.....
        }
    }
}
<UserControl.Style>
    <Style>
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsSaveCanvas}" Value="True">
                <Setter Property="wpfApplication1:Behaviours.SaveCanvas" Value="True"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsSaveCanvas}" Value="False">
                <Setter Property="wpfApplication1:Behaviours.SaveCanvas" Value="False"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Style>

可以使用CommandParameter将画布传递给ViewModel的Save方法

<Button Content="Save" 
        Command="{Binding SaveCanvasCommand}" 
        CommandParameter="{Binding ElenementName=myCanvas}" ?>

<Canvas x:Name="myCanvas">
   <!-- Stuff to save -->
</Canvas>

您正在寻找如何使用MVVM进行绑定吗?(MVVM light RelayCommand)根本不是WPF成员,但您的代码是否违反了MVVM原则,即不应在VM内部访问UI元素?