我正在尝试将SelectedItem绑定到View。但是当视图位于Resources块内时,视图无法访问viewmodel。 将datacontext重新分配给子项时,绑定适用于文本块,但不适用于UserControl(NoteView)
我错过了任何绑定吗?
PFB修订(整个)代码和内联评论。
<UserControl x:Class="Konduva.View.NoteSearchView"
<!-- other namespaces here -->
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
DataContext="{Binding NoteSearch, Source={StaticResource Locator}}">
<Grid>
<ListView ItemsSource="{Binding Notes}"
SelectedItem="{Binding SelectedNote}">
<ListView.Resources>
<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>
<!-- This is working --> <TextBlock Text="{Binding SelectedNote.Title}" />
<!-- This is not working --> <v:NoteView DataContext="{Binding SelectedNote}" />
</StackPanel>
</Popup>
</DockPanel>
</DataTemplate>
</ListView.Resources>
</ListView>
</Grid>
</UserControl>
NoteView:
<Grid>
<TextBlock Text="{Binding Title}" /> // This Text is not displayed
</Grid>
答案 0 :(得分:2)
更新3 由于您使用的是MvvmLight:在NoteView中,请尝试更改
DataContext="{Binding Note, Source={StaticResource Locator}}"
到
<UserControl.Style>
<Style TargetType="UserControl">
<Setter Property="DataContext" Value="{Binding Note, Source={StaticResource Locator}}"/>
</Style>
</UserControl.Style>
更新2
几分钟前遇到类似的问题,我并没有完全理解,所以我会在这里提出相同的解决方案,看看是否有帮助。如果你改变它会发生什么?
<v:NoteView DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type Popup}},
Path=DataContext.SelectedNote}"/>
<强>更新强>
我无法重现这一点。尝试在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由所有Childs继承,因此每个子节点都将以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>
答案 1 :(得分:1)
不使用直接插入NoteView并绑定DataContext,而是使用ContentPresenter:
<ContentPresenter Content="{Binding SelectedNote}>
<ContentPresenter.ContentTemplate>
<DataTemplate>
<v:NoteView />
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>