WPF - 用户控件中的 MVVM 绑定

WPF - MVVM binding in UserControl

我正在测试 MVVM 模式中的示例绑定。我正在使用包 GalaSoft.MvvmLight。从 MainViewModel 绑定到 MainWindow 是正常的,但我无法将数据从 ViewModel (ImageViewModel) 绑定到 View (ImageView)。我所有的代码都在下面

在App.xaml

<Application x:Class="WpfApplication1.App"         
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr- 
namespace:WpfApplication1" StartupUri="MainWindow.xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d1p1:Ignorable="d" 
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Application.Resources>
<ResourceDictionary>
  <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr- 
  namespace:WpfApplication1.ViewModel" />
</ResourceDictionary>
</Application.Resources>
</Application>

在MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:v="clr-namespace:WpfApplication1.View"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    DataContext="{Binding Main, Source={StaticResource Locator}}"
    mc:Ignorable="d"
    Title="MainWindow" Height="800" Width="1000">
<Grid>
    <Grid Grid.Column="1">
        <v:ImageView DataContext="{Binding ImageVM}"/>
    </Grid>
       
</Grid>

在ImageView.xaml

<UserControl x:Class="WpfApplication1.View.ImageView"
         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:WpfApplication1.View"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
         Name="ucImage">

<UserControl.DataContext>
    <Binding Path="Main.ImageVM" Source="{StaticResource Locator}"/>
</UserControl.DataContext>

<Grid>
    <TextBox x:Name="label" Text="{Binding TestText, ElementName=ucImage}" Width="100" 
     Height="50"/>
</Grid>
</UserControl>

在ViewModelLocator.cs

using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApplication1.ViewModel
{
public class ImageViewModel: ViewModelBase
{
    public string _TestText;
    public string TestText
    {
        get
        {
            return _TestText;
        }
        set
        {
            _TestText = value;
            RaisePropertyChanged(() => this.TestText);
        }
    }


    public ImageViewModel()
    {
        TestText = "asdasdasdasdas";
    }
}
}

在 MainViewModel 中

public class MainViewModel : ViewModelBase
{
    private ImageViewModel _ImageVM;
    public ImageViewModel ImageVM
    {
        get { return _ImageVM; }
        set { Set(ref _ImageVM, value); }
    }


    public MainViewModel()
    {
        ImageVM = new ImageViewModel();
    }
}

在ImageViewModel.cs

using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApplication1.ViewModel
{
public class ImageViewModel: ViewModelBase
{
    public string _TestText;
    public string TestText
    {
        get
        {
            return _TestText;
        }
        set
        {
            _TestText = value;
            RaisePropertyChanged(() => this.TestText);
        }
    }


    public ImageViewModel()
    {
        TestText = "asdasdasdasdas";
    }
}

}

输出的这个错误是

System.Windows.Data Error: 40 : BindingExpression path error: 'TestText' property not found on 'object' ''ImageView' (Name='ucImage')'. BindingExpression:Path=TestText; DataItem='ImageView' (Name='ucImage'); target element is 'TextBox' (Name='label'); target property is 'Text' (type 'String')

任何想出解决方案的人都将不胜感激!

表达式

Text="{Binding TestText, ElementName=ucImage}"

期望 ImageView 控件中有一个 TestText 属性,它显然不存在 - 这就是错误消息所说的。

您只需编写以下内容即可使控件 XAML 中的元素直接绑定到其 DataContext 中的视图模型对象:

<TextBox Text="{Binding TestText}" .../>

为了使控件独立于特定的视图模型,它应该公开一个可绑定的 属性,即依赖项 属性,如下所示:

public partial class ImageView : UserControl
{
    public ImageView()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register(
            nameof(Text), typeof(string), typeof(ImageView));

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
}

可用于

<TextBox Text="{Binding Text, ElementName=ucImage}"

在控件的 XAML 中并且没有显式设置控件的 DataContext,即在其 XAML.

中没有 <UserControl.DataContext> 部分

属性 会像

一样绑定
<v:ImageView DataContext="{Binding ImageVM}" Text="{Binding TestText}"/>

或者只是

<v:ImageView Text="{Binding ImageVM.TestText}"/>