如何将TextBox中的值绑定到Mvvm Light中的viewmodel

时间:2014-11-05 23:16:13

标签: c# wpf binding visual-studio-2013 mvvm-light

我一直在研究使用MVVM Light的示例项目,我想知道如何绑定TextBox Text值并将其传递给View和View模型。这是我第一次使用MVVM Light,所以我是新手。

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

查看:

<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>

视图模型:

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");
            }
        }
    }
}

那么如何将ProjName绑定传递给View以及从View MOdel传递?

3 个答案:

答案 0 :(得分:2)

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

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

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>

第一个似乎对我的正常需求更加灵活......

答案 1 :(得分:1)

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

public MyViewModel ModelView;

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

一旦页面的datacontext设置如上所示,控件datacontext,如果没有设置,走向其父级的可视树,直到设置了datacontext;这是在页面上完成的,最终的父母。

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

答案 2 :(得分:1)

从用户键入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.