MVVM WPF 中的数据绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29058874/
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 13:00:50  来源:igfitidea点击:

Data Binding in MVVM WPF

c#wpfxamlmvvm

提问by harikrishnan.n0077

I have little knowledge in MVVM pattern. My problem is the data does not get binded to the xaml controls, no error is there. The progressbar is still at 0.

我对 MVVM 模式知之甚少。我的问题是数据没有绑定到 xaml 控件,没有错误。进度条仍为 0。

HomepageViewModel

主页视图模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using CSMS_MVVM.Models;

namespace CSMS_MVVM.ViewModels
{
    class HomepageViewModel : INotifyPropertyChanged
    {
        BackgroundWorker _worker;
        public int _progress=20;
        public int Progress
        {
            get { return _progress; }
            set {
                _progress = value;
                OnPropertyChanged(new PropertyChangedEventArgs("Progress"));
            }
        }
        public void startBackgroundProcess()
        {
            _worker = new BackgroundWorker();
            _worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            _worker.ProgressChanged += worker_Progress_Changed;
            _worker.RunWorkerAsync();
        }

        private void worker_Progress_Changed(object sender, ProgressChangedEventArgs e)
        {
            Progress = e.ProgressPercentage;
        }

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Progress = 20;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, e);
        }

        #endregion
    }
}

Homepage.xaml.cs

主页.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CSMS_MVVM.ViewModels;

namespace CSMS_MVVM.Views
{
    /// <summary>
    /// Interaction logic for Homepage.xaml
    /// </summary>
    public partial class Homepage : Page
    {
        HomepageViewModel hvm;
        public Homepage()
        {
            InitializeComponent();
        }

        private void Page_Loaded_1(object sender, RoutedEventArgs e)
        {
            hvm = new HomepageViewModel();
            hvm.startBackgroundProcess();
        }
    }
}

Homepage.xaml

主页.xaml

<Page x:Class="CSMS_MVVM.Views.Homepage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:CSMS_MVVM.ViewModels"
      mc:Ignorable="d" 
      d:DesignHeight="700" d:DesignWidth="1000"
    Title="Homepage" Loaded="Page_Loaded_1" Name="main">
<ProgressBar Name="pbStatus" Value="{Binding Path=Progress}" HorizontalAlignment="Center" Height="20" Margin="0,582,0,0" VerticalAlignment="Top" Width="300">
-----
            <ProgressBar.Effect>
                <DropShadowEffect Color="#FFB6B6B6" ShadowDepth="3" BlurRadius="15" Direction="310"/>
            </ProgressBar.Effect>
        </ProgressBar>
        <TextBlock Text="{Binding Progress}" Margin="0,582,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" />
        <Label Content="Loading ..." HorizontalAlignment="Center" Margin="0,607,0,0" VerticalAlignment="Top"/>
------
</Page>

Am i doing the correct coding? I searched the internet for an example but i did not understand them.

我在做正确的编码吗?我在互联网上搜索了一个例子,但我不明白它们。

Thanks!

谢谢!

回答by nvoigt

All bindings you set will bind to the DataContextif nothing else is specified.

DataContext如果未指定其他任何内容,则您设置的所有绑定都将绑定到。

private void Page_Loaded_1(object sender, RoutedEventArgs e)
{
    hvm = new HomepageViewModel();
    hvm.startBackgroundProcess();

    this.DataContext = hvm;
}

Once you have your data context set to your viewmodel instance, it should work.

将数据上下文设置为视图模型实例后,它应该可以工作。

回答by Andrew Shepherd

You can set the DataContext of the page in the code behind.

可以在后面的代码中设置页面的DataContext。

Another option is to create the ViewModel as a XAML resource, and set the data context of the child element via Data Binding:

另一种选择是将 ViewModel 创建为 XAML 资源,并通过数据绑定设置子元素的数据上下文:

<Page x:Class="CSMS_MVVM.Views.Homepage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  xmlns:local="clr-namespace:CSMS_MVVM.ViewModels"
  mc:Ignorable="d" 
  d:DesignHeight="700" d:DesignWidth="1000"
Title="Homepage" Loaded="Page_Loaded_1" Name="main">
  <Page.Resources>
        <!-- This creates the instance of the HomepageViewModel -->
        <local:HomepageViewModel x:Key="HomepageViewModel" />
  </Page.Resources>
  <ProgressBar DataContext="{StaticResource HomepageViewModel}" 
        Value="{Binding Path=Progress}">

回答by Abhinav Singh

public Homepage()       
{        
   InitializeComponent();      
   hvm = new HomepageViewModel();
   this.DataContext=hvm;      
}

Create view model object inside constructor.

在构造函数中创建视图模型对象。