我花了一天的时间查看有关该主题的其他问题,但无法使该特定代码正常工作。
背景:我们使用 Prism 自动注册视图的视图模型,并使用 Prism 的 DI 容器注入服务。该应用程序基于可重用的用户控件构建。因此,特定的用户控件可能会出现在不同的窗口上(或者显然,同一窗口的多个实例)。例如,我们有一个带有五个不同用户控件的公司窗口。每个用户控件的视图模型必须从父窗口的视图模型获取 CompanyId,以便它可以使用该 CompanyId 来调用各种服务等。
我尝试在没有 Prism 的情况下使用社区 MVVM 工具包设置一个简单的示例,但运气不佳。
窗口 XAML:
<Window
x:Class="BindingDependencyProperties.MainWindow"
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:local="clr-namespace:BindingDependencyProperties"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0">
<Run Text="{Binding CompanyIdFromWin}" />
</TextBlock>
<local:CompanyUserControl Grid.Row="1" CompanyId="{Binding CompanyIdFromWin}" />
<local:CompanyUserControl Grid.Row="2" CompanyId="hardcoded" />
</Grid>
</Window>
窗口代码隐藏:
namespace BindingDependencyProperties
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
窗口虚拟机:
namespace BindingDependencyProperties
{
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private string _companyIdFromWin;
public MainWindowViewModel()
{
CompanyIdFromWin = "test123";
}
}
}
用户控制XAML:
<UserControl x:Class="BindingDependencyProperties.CompanyUserControl"
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:BindingDependencyProperties"
d:DataContext="{d:DesignInstance Type=local:CompanyUserControlViewModel, IsDesignTimeCreatable=True}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock>
<Run Text="Company ID: " />
<Run Text="{Binding CompanyId}" />
</TextBlock>
</Grid>
</UserControl>
背后的用户控制代码:
namespace BindingDependencyProperties
{
public partial class CompanyUserControl : UserControl
{
private CompanyUserControlViewModel _viewModel;
public string CompanyId
{
get { return (string)GetValue(CompanyIdProperty); }
set { SetValue(CompanyIdProperty, value); }
}
public static readonly DependencyProperty CompanyIdProperty =
DependencyProperty.Register("CompanyId", typeof(string), typeof(CompanyUserControl),
new PropertyMetadata(string.Empty));
public CompanyUserControl()
{
InitializeComponent();
_viewModel = new CompanyUserControlViewModel();
this.DataContext = _viewModel;
}
}
}
用户控制虚拟机:
public partial class CompanyUserControlViewModel : ObservableObject
{
[ObservableProperty]
private string _companyId = string.Empty;
}
当我运行应用程序时,我看到:
CompanyId 没有流入用户控制虚拟机。请注意,我确实尝试不使用 MVVM Toolkit,手动实现 INotifyPropertyChanged 以及支持属性和处理程序,但结果相同。
那么,
我在这里做错了什么?
public CompanyUserControl()
{
InitializeComponent();
_viewModel = new CompanyUserControlViewModel();
this.DataContext = _viewModel;
}
这不是一个可重用的控件,它非常具体和专业。没关系,所有应用程序都有它,主要用于顶级视图或页面。这些还利用 Prism 的视图模型定位器。
但是,在您的情况下,您希望控件从其他人那里接收其视图模型,例如通过将
ItemsControl
的 ItemsSource
绑定到父视图模型上的集合属性,并通过 ItemTemplate
创建控件。