wpf 如何将 TextBox 中的值绑定到 Mvvm Light 中的视图模型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26768985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:40:51  来源:igfitidea点击:

How to bind a value from a TextBox to the viewmodel in Mvvm Light

c#wpfbindingvisual-studio-2013mvvm-light

提问by yams

I've been working on a sample project using MVVM Light and I'm wondering how to bind a TextBox Text value and have it passed to and from the View to the View Model. This is the first time I've worked with MVVM Light so I'm new to this.

我一直在使用 MVVM Light 处理一个示例项目,我想知道如何绑定 TextBox 文本值并将它传递到视图和从视图传递到视图模型。这是我第一次使用 MVVM Light,所以我是新手。

Basically a user will enter a Project name in to the Text Box name and click the New Project button which should generate a database named after what was typed in to the Project Name Text Box.

基本上,用户将在文本框名称中输入项目名称,然后单击“新建项目”按钮,该按钮应生成一个以在“项目名称”文本框中键入的内容命名的数据库。

View :

看法 :

<UserControl x:Class="Sample.Views.NavigationTree.NewProjectView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mui="http://firstfloorsoftware.com/ModernUI"
        xmlns:ignore="http://www.ignore.com"
        mc:Ignorable="d ignore"
        DataContext="{Binding NewProjectView, Source={StaticResource Locator}}">

    <Grid>
        <StackPanel Orientation="Vertical" HorizontalAlignment="Left">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                <mui:BBCodeBlock BBCode="Project Name"/>
                <Label Width="10"/>
                <TextBox Text="{Binding ProjName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Width="120"/>
            </StackPanel>
            <Label Height="10"/>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                <Label Width="85"/>
                <Button Content="New Project" Margin="0,0,3,0" Command="{Binding AddProjectCommand}" IsEnabled="{Binding IsUserAdmin}" Grid.Column="2" Grid.Row="0"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</UserControl>

ViewModel:

视图模型:

using Sample.Model.Database;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Text;

namespace Sample.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class NewProjectViewModel : ViewModelBase
    {
        private string _projName;
        //Binding AddProjectCommand
        public RelayCommand AddProjectCommand { get; set; }


        private string consoleText { get; set; }
        private StringBuilder consoleBuilder = new StringBuilder(360);
        /// <summary>
        /// Initializes a new instance of the NewProjectViewModel class.
        /// </summary>
        public NewProjectViewModel()
        {
            this.AddProjectCommand = new RelayCommand(() => AddProject());
        }

        public void AddProject()
        {
            ProjectDbInteraction.CreateProjectDb(_projName);

        }


        public string ProjName
        {
            get { return _projName; }
            set
            {
                if (value != _projName)
                {
                    _projName = value;
                    RaisePropertyChanged("ProjName");
                }
            }
        }

        public string ConsoleText
        {
            get { return consoleText; }
            set
            {
                consoleBuilder.Append(value);
                consoleText = consoleBuilder.ToString();
                RaisePropertyChanged("ConsoleText");
            }
        }
    }
}

So how do I pass the ProjName binding to and from the View to the View MOdel?

那么如何将 ProjName 绑定传递到视图和从视图传递到视图模型?

回答by Theodosius Von Richthofen

Looks good, you just need to create an association between the View and ViewModel. Basically, set your DataContext of your view to the ViewModel.

看起来不错,你只需要在 View 和 ViewModel 之间创建一个关联。基本上,将视图的 DataContext 设置为 ViewModel。

You can do this a few ways, i will show two: 1) In the code-behind of your view, you can create an instance of your viewmodel (ViewModel vm=new ViewModel()) as then assign it with this.DataContext=vm; 2) You can XAML Data Templates. Something like this, where Home is a view and HomeVM is viewmodel.

您可以通过几种方式做到这一点,我将展示两种方式:1)在您的视图的代码隐藏中,您可以创建一个视图模型的实例(ViewModel vm=new ViewModel()),然后用 this.DataContext= 分配它虚拟机;2) 您可以使用 XAML 数据模板。像这样,Home 是一个视图,HomeVM 是一个视图模型。

in

<Window
.
.
.
    xmlns:HomeView="clr-namespace:Bill.Views"
    xmlns:HomeVM="clr-namespace:Bill.ViewModels"
>

    <Window.Resources>
        <!--Home User Control and View Model-->
            <DataTemplate DataType="{x:Type HomeVM:HomeVM}">
                <HomeView:Home/>
            </DataTemplate>
    </Window.Resources>

The first seems more flexible for my normal needs...

第一个似乎更适合我的正常需求......

回答by ΩmegaMan

Your textbox binding looks correct. What is not shown is how you associate your ViewModel to the datacontext of the page which can ultimately be consumed by the textbox. I would recommend that you do this in the code behind of the page.

您的文本框绑定看起来正确。未显示的是您如何将 ViewModel 与最终可由文本框使用的页面的数据上下文相关联。我建议您在页面后面的代码中执行此操作。

public MyViewModel ModelView;

public MainWindow()
{
    InitializeComponent();
    DataContext = ModelView = new MyViewModel ();
}

Once the page's datacontext is set as shown above, the controls datacontext, if not set, walks up the visualtree of its parent(s) until a datacontext has been set; which is done here on the page, the ultimate parent.

一旦页面的数据上下文设置为如上所示,控件数据上下文(如果未设置)将向上遍历其父级的可视化树,直到设置了数据上下文;这是在页面上完成的,最终的父级。

I provide a more robust example on my blog article Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding.which can show you how to rollyour own MVVM (which is all MVVM light does).

我在我的博客文章Xaml 中提供了一个更强大的示例:ViewModel Main Page Instantiation and Loading Strategy for Easier Binding。它可以向您展示如何滚动您自己的 MVVM(这是 MVVM 灯所做的全部)。

回答by Theodosius Von Richthofen

Remove "Mode=OneWay" from your binding of the textbox where the user types the ProjName, this will allow your property to receive the value. Or choose one of the other Modes that do what you want.

从用户键入 ProjName 的文本框的绑定中删除“Mode=OneWay”,这将允许您的属性接收该值。或者选择其他一种模式来做你想做的事。

OneWay: use this when you want the data in view model to modify the value in your GUI
TwoWay: use this if you want to allow view model to modify the GUI value, or if you want the GUI value changed by the user to be reflected in view model
OneTime: your view model can set the value that is shown in your GUI once, and it will never change again. Only do this if you know you're not going to need to change the value in your view model.
OneWayToSource: This is the opposite of one way -- GUI value affects view model value.