Невозможно получить доступ к свойствам viewmodel изнутри Listvew.Resources

Я пытаюсь привязать SelectedItem к представлению. Но представление не может получить доступ к viewmodel, когда оно находится внутри блока Resources. Когда 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}"> 
 </v:noteview></textblock></stackpanel>
 </popup>
 </textblock></dockpanel>
 </datatemplate>
 </listview.resources> 
 </listview> 
 </grid>
</usercontrol>

NoteView:

<grid>
 <textblock text="{Binding Title}"> // This Text is not displayed
</textblock></grid>
2 ответа

Обновление 3 Поскольку вы используете MvvmLight: в NoteView попробуйте изменить

DataContext="{Binding Note, Source={StaticResource Locator}}"

к

<usercontrol.style>
 
</usercontrol.style>

Обновление 2

Обнаружена аналогичная проблема несколько минут назад, которую я не полностью понял, поэтому я брошу туда же решение, чтобы узнать, помогает ли она. Что происходит, если вы измените его на это?

Обновление

Я не могу воспроизвести это. Попробуйте добавить это в свой конструктор NoteView. Вы попадаете в DataContextChangedHandler, когда вы меняете выделение в ListView?

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 в качестве DataContext для всплывающего окна, вы можете это сделать. Я не уверен, что делает DataContext Binding для StackPanel, поэтому я мог бы что-то пропустить здесь.

<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}">
 </v:noteview></stackpanel>
 </textblock></stackpanel>
 </popup>
 </textblock></dockpanel>
</datatemplate>


Вместо того, чтобы вставлять NoteView напрямую и привязывать DataContext, используйте ContentPresenter:

licensed under cc by-sa 3.0 with attribution.