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}"/>
我正在测试 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}"/>