I don't understand how I can create a command to create a MVVM clickable rectangle. Here is my code:
<Rectangle x:Name="Color01" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="100" Margin="10,29,0,0" Stroke="Black" VerticalAlignment="Top" Width="100" MouseDown="Color_MouseDown" />
<Rectangle x:Name="Color02" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="100" Margin="115,29,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"/>
<Rectangle x:Name="Color03" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="100" Margin="220,29,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"/>
<Rectangle x:Name="Color04" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="100" Margin="325,29,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"/>
On my first rectangle you can see I created a code behind event. First I don't know how to access my ViewModel from the code behind. Two it's not really MVVM.
public partial class MainWindow : Window
{
/// <summary>
/// Initializes a new instance of the MainWindow class.
/// </summary>
public MainWindow()
{
InitializeComponent();
Closing += (s, e) => ViewModelLocator.Cleanup();
}
private void Color_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// So what ???
}
}
I just need to be able to change a simple boolean value stored in a list stored in my viewModel when someone click on my rectangle. Why it is so complicate to do with MVVM?
This isn't too difficult. First, create an instance of your ViewModel inside your Window XAML:
View XAML:
<Window x:Class="BuildAssistantUI.BuildAssistantWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:MySolutiom.ViewModels">
<Window.DataContext>
<VM:MainViewModel />
</Window.DataContext>
</Window>
After that, you can System.Windows.Interactivity.InvokeCommandAction
to translate your event to a command:
View XAML:
<Grid>
<Rectangle x:Name="Color01" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="100" Margin="10,29,0,0" Stroke="Black" VerticalAlignment="Top" Width="100" MouseDown="Color_MouseDown"> <interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="MouseDown">
<interactivity:InvokeCommandAction Command="{Binding MyCommand}"/>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</Rectangle>
</Grid>
Now, in your ViewModel, set up an ICommand
and the DelegateCommand
implementation to bind to that event:
ViewModel:
public class ViewModel
{
public ICommand MyCommand { get; set; }
public ViewModel()
{
MyCommand = new DelegateCommand(OnRectangleClicked);
}
public void OnRectangleClicked()
{
// Change boolean here
}
}
In MVVM you shouldn't be accessing your view model from code behind, the view model and view are ignorant of each other a here endeth the lecture :)
Instead you can attach the EventToCommand behaviour to your control. This lets you bind an event in the control to a command in the data context. See msdn commands tutorial here.
If you are desperate to do it, you can access the controls data context property and cast it to your view model type to give access to the internals.
var vm = (ViewModelType)this.DataContext;
vm.CommandProperty.Execute(null);
Quick answer. This might help others as well
((MyViewModel)(this.DataContext)).MyProperty