Update 3由于您在 NoteView 中使用 MvvmLight:,请尝试更改
DataContext="{Binding Note, Source={StaticResource Locator}}"
to
<UserControl.Style>
<Style TargetType="UserControl">
<Setter Property="DataContext" Value="{Binding Note, Source={StaticResource Locator}}"/>
</Style>
</UserControl.Style>
Update 2
几分钟前遇到了类似的问题,我没有完全理解,所以我将在这里提出相同的解决方案,看看它是否有帮助。如果你把它改成这样会发生什么?
<v:NoteView DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type Popup}},
Path=DataContext.SelectedNote}"/>
Update
我无法重现这个。尝试将其添加到您的 NoteView 构造函数中。当您更改 ListView 中的选择时,您是否会到达 DataContextChangedHandler?
public NoteView()
{
InitializeComponent();
DependencyPropertyDescriptor dpd =
DependencyPropertyDescriptor.FromProperty(UserControl.DataContextProperty,
typeof(UserControl));
if (dpd != null)
{
dpd.AddValueChanged(this, new EventHandler(DataContextChangedHandler));
}
}
void DataContextChangedHandler(object sender, EventArgs e)
{
MessageBox.Show("DataContext Changed: " + DataContext);
}
第一个答案
您的 DockPanel 将获取 NoteViewModel 作为 DataContext,而不是 ListView,并且由于此 DataContext 被所有子级继承,所以每个子级最终都会得到 NoteViewModel 作为 DataContext。要将 ListView 用作 Popup 的 DataContext,您可以执行此操作。我不确定 StackPanel 的 DataContext 绑定会做什么,所以我可能会在这里遗漏一些东西。
<DataTemplate DataType="{x:Type vm:NoteViewModel}">
<DockPanel>
<TextBlock Text="{Binding Title}" />
<Popup Placement="Right"
PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}"
IsOpen="{Binding (ListViewItem.IsSelected), RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}"
DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}">
<StackPanel>
<TextBlock Text="{Binding SelectedNote.Title}" />
<StackPanel>
<v:NoteView DataContext="{Binding SelectedNote}"/>
</StackPanel>
</StackPanel>
</Popup>
</DockPanel>
</DataTemplate>