How can I access my ViewModel from code behind

2019-03-15 14:23发布

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?

标签: c# wpf mvvm
3条回答
forever°为你锁心
2楼-- · 2019-03-15 14:58

Quick answer. This might help others as well

((MyViewModel)(this.DataContext)).MyProperty
查看更多
手持菜刀,她持情操
3楼-- · 2019-03-15 14:59

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
    }
}
查看更多
姐就是有狂的资本
4楼-- · 2019-03-15 14:59

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);
查看更多
登录 后发表回答