【问题标题】:How to bind a value from a TextBox to the viewmodel in Mvvm Light如何将文本框中的值绑定到 Mvvm Light 中的视图模型
【发布时间】:2014-11-05 23:16:13
【问题描述】:

我一直在使用 MVVM Light 开发一个示例项目,我想知道如何绑定一个 TextBox 文本值并将其传递到视图以及从视图传递到视图模型。这是我第一次使用 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 绑定传递给视图和视图模型?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    第一个似乎更灵活地满足我的正常需求......

    【讨论】:

    • 我添加了整个视图和视图模型。
    • 您是否尝试通过让用户在文本框中键入来设置 ProjName 属性?如果是这样,您不能在那里使用单向绑定。如果您需要,请将其删除或设置为 TwoWay 或 OneWayToSource。 OneWay 仅适用于来自您的视图模型的价值
    • 哦该死的你是对的。根本没想过。
    • 那解决了你的问题吗?
    【解决方案2】:

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

    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 light 所做的)。

    【讨论】:

    • 我已经添加了整个视图和视图模型,并尝试在后面的代码中设置数据上下文,但视图模型中的 _projName 仍然为 Null。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 2012-07-31
      • 2011-10-07
      相关资源
      最近更新 更多