我正在使用Caliburn Micro学习MVVM。我有两个视图:ShellView
(主窗口(和PersonView
(用户控制(。ShellView可以毫无问题地正确绑定到ShellViewModel,但它似乎没有将用户控件正确绑定到其关联的ViewModel。
我在ShellViewModel
中初始化了一个属性MyPerson
,它与ShellView
中控件的x:Name
匹配,根据CM约定,它应该将DataContext绑定到PersonViewModel(我从这篇SO文章中得到了这种方法(,但它没有。绑定标签显示CMTestUserControlMVVM.ViewModels.ShellViewModel
。
我明确地将DataContext添加到UserControl中的ViewModel中以修复此问题。
DataContext="CMTestUserControlMVVM.ViewModels.PersonViewModel";
我用绑定标签验证了它,因为它显示CMTestUserControlMVVM.ViewModels.PersonViewModel
,但我现在有以下问题:
- ViewModel中的属性和操作没有绑定。初始化的MyPerson的值不会被反映,按钮
SayMyName
也不会执行任何操作 - 属性不会暴露在主窗口中。我最终想将PersonView控件的FirstName和LastName道具绑定到Shell视图中的其他控件
如何修复这些问题?以下是相关的代码。
ShellView.xaml:
<Window x:Class="CMTestUserControlMVVM.Views.ShellView"
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:local="clr-namespace:CMTestUserControlMVVM.Views"
mc:Ignorable="d"
Title="ShellView" Height="450" Width="800"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Width="100" x:Name="DoSomething" Content="Do Something"/>
<local:PersonView Grid.Row="1" x:Name="MyPerson"
Width="350" Height="100"
/>
<Label Content="{Binding}" Grid.Row="2" />
</Grid>
关联视图模型:
namespace CMTestUserControlMVVM.ViewModels
{
public class ShellViewModel : Screen
{
private PersonViewModel model;
public PersonViewModel MyPerson
{
get { return model; }
set
{
model = value;
NotifyOfPropertyChange(() => MyPerson);
}
}
public ShellViewModel()
{
MyPerson = new PersonViewModel()
{
FirstName = "Shameel",
LastName = "Mohammed"
};
}
public void DoSomething()
{
MessageBox.Show("Doing Something");
}
}
}
PersonView.xaml:
<UserControl x:Class="CMTestUserControlMVVM.Views.PersonView"
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:CMTestUserControlMVVM.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
DataContext="CMTestUserControlMVVM.ViewModels.PersonViewModel"
>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="FirstName"/>
<TextBlock x:Name="LastName"/>
</StackPanel>
<Button Grid.Row="1" x:Name="SayMyName" Content="Say My Name!"/>
<Label Grid.Row="2" Content="{Binding}"/>
</Grid>
关联视图模型:
namespace CMTestUserControlMVVM.ViewModels
{
public class PersonViewModel : PropertyChangedBase
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
NotifyOfPropertyChange(() => FirstName);
}
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
NotifyOfPropertyChange(() => LastName);
}
}
public void SayMyName()
{
MessageBox.Show($"Hi {FirstName} {LastName}!");
}
}
}
-
删除
DataContext="CMTestUserControlMVVM.ViewModels.PersonViewModel"
,因为这会将DataContext
设置为string
文字,这毫无意义。 -
在ShellView.xaml:中将
UserControl
替换为ContentControl
<ContentControl Grid.Row="1" x:Name="MyPerson" Width="350" Height="100" />