Saving a WPF canvas as an image following MVVM Pattern

元气小坏坏 提交于 2019-12-04 06:34:25

You could pass the Canvas to the ViewModel's Save method using a CommandParameter

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

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

And somewhere in you ViewModel or Command you'd have

void SaveCanvasCommandExecute(object parameter)
{
    UIElement toSave = (UIElement)parameter;
    //.. You'd probably use RenderTargetBitmap here to save toSave.
}

If you don't want to reference UI elements in your ViewModel you could use an attached behaviour:

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.....
        }
    }
}

Then in your ViewModel you have your Command that sets a property, also on your ViewModel:

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

            return _saveCanvasCommand;
        }
    }

And the property which is bound to your View:

    public bool IsSaveCanvas
    {
        get { return _isSaveCanvas; }
        set
        {
            _isSaveCanvas = value;
            RaisePropertyChanged("IsSaveCanvas");
        }
    }

Then hooking it all up in the Xaml looks like this:

Add a Trigger on the Control that binds the value of your ViewModel property to your attached behaviour:

<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>

And then bind your Button / MenuItem to the ViewModels Save Command:

    <Canvas.ContextMenu>
        <MenuItem Header="Save" Command="{Binding SaveCanvasCommand}"/>
    </Canvas.ContextMenu>
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!