Saving WPF canvas as image after MVVM template

I have a canvas, for example. similar to this solution or many others using ItemsControl .

Now I want a button that should be bound to ICommand. This command should call the method of the ViewModel class, which can save the image. The save method is clear, but how do I bind after the MVVM pattern?

+6
source share
2 answers

You can pass the Canvas to the ViewModel Save method using CommandParameter

 <Button Content="Save" Command="{Binding SaveCanvasCommand}" CommandParameter="{Binding ElenementName=myCanvas}" ?> <Canvas x:Name="myCanvas"> <!-- Stuff to save --> </Canvas> 

And somewhere in your ViewModel or Command you will have

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

If you do not want to reference user interface elements in the ViewModel, you can use the attached behavior:

 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 a command that sets the property, also on your ViewModel:

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

And the property tied to your view:

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

Then intercepting everything in Xaml is as follows:

Add a Trigger to Control , which binds the value of the ViewModel property to your nested behavior:

 <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> 
+1
source

Source: https://habr.com/ru/post/949629/


All Articles