如何从后面的代码访问我的ViewModel

Bas*_*mme 11 c# wpf mvvm

我不明白如何创建命令来创建MVVM可点击矩形.这是我的代码:

<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"/>
Run Code Online (Sandbox Code Playgroud)

在我的第一个矩形上,您可以看到我在事件后面创建了一个代码 首先,我不知道如何从后面的代码访问我的ViewModel.二,它不是真正的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 ???
    }
}
Run Code Online (Sandbox Code Playgroud)

当有人点击我的矩形时,我只需要能够更改存储在viewModel中的列表中存储的简单布尔值.为什么MVVM如此复杂?

kid*_*haw 24

在MVVM中,您不应该从后面的代码访问您的视图模型,视图模型和视图彼此无知在这里演讲:)

相反,您可以将EventToCommand行为附加到您的控件.这使您可以将控件中的事件绑定到数据上下文中的命令.请参阅此处的msdn命令教程.

如果您迫切希望这样做,您可以访问控件数据上下文属性并将其转换为您的视图模型类型以访问内部.

var vm = (ViewModelType)this.DataContext;
vm.CommandProperty.Execute(null);
Run Code Online (Sandbox Code Playgroud)

  • 这并不完全正确。由于您将“DataContext”属性设置为指向 View 中的 ViewModel,因此它们是绑定的。此外,所有“Binding”再次了解 ViewModel 中定义的属性。所以View总是知道ViewModel。然而,相反的情况是不正确的:ViewModel 永远不应该绑定到 View。 (6认同)

Yuv*_*kov 10

这不是太难.首先,在Window XAML中创建ViewModel的实例:

查看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>
Run Code Online (Sandbox Code Playgroud)

之后,您可以System.Windows.Interactivity.InvokeCommandAction将事件转换为命令:

查看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>
Run Code Online (Sandbox Code Playgroud)

现在,在ViewModel中,设置一个ICommandDelegateCommand要绑定到该事件的实现:

视图模型:

public class ViewModel
{
    public ICommand MyCommand { get; set; }

    public ViewModel()
    {
        MyCommand = new DelegateCommand(OnRectangleClicked);
    }

    public void OnRectangleClicked()
    {
        // Change boolean here
    }
}
Run Code Online (Sandbox Code Playgroud)


Cha*_*ena 7

快速回答.这也可能有助于其他人

((MyViewModel)(this.DataContext)).MyProperty
Run Code Online (Sandbox Code Playgroud)

  • 将“DataContext”更改为“BindingContext”对我有用。 (2认同)

Var*_*mus 7

在 C# XAML UWP MVVM 上下文中。

考虑下面的例子

模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FrostyTheSnowman.Models
{
    public class User
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }        

        public override string ToString() => $"{FirstName} {LastName}";

    }
}
Run Code Online (Sandbox Code Playgroud)

视图模型

using FrostyTheSnowman.Models;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FrostyTheSnowman
{
    public class MainPageViewModel
    {
        public User user { get; set; }

        public MainPageViewModel()
        {
            user = new User
            {
                FirstName = "Frosty",
                LastName = "The Snowman"                
            };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

看法

<Page
    x:Class="FrostyTheSnowman.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:FrostyTheSnowman"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Page.DataContext>
        <local:MainPageViewModel x:Name="ViewModel" />
    </Page.DataContext>

    <Grid>
        <StackPanel Name="sp1" DataContext="{Binding user}">

            <TextBox Name="txtFirstName"                     
                 Header="First Name"
                 Text="{Binding FirstName}" />

            <TextBox Name="txtLastName"                     
                 Header="Last Name"
                 Text="{Binding LastName}" />


        </StackPanel>

    </Grid>
</Page>
Run Code Online (Sandbox Code Playgroud)

代码隐藏文件:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace FrostyTheSnowman
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        MainPageViewModel vm;

        public MainPage()
        {
            this.InitializeComponent();

            // Initialize the View Model Object
            vm = (MainPageViewModel)this.DataContext;

            System.Diagnostics.Debug.WriteLine(vm.user.ToString() + " was a jolly happy soul");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当你运行该应用程序时,你会看到:

在此输入图像描述

但更重要的是,调试跟踪将显示:

在此输入图像描述

它表明代码隐藏确实已成功访问ViewModel...

希望这可以帮助