编程语言
首页 > 编程语言> > c#-无法从Listvew.Resources内部访问viewmodel属性

c#-无法从Listvew.Resources内部访问viewmodel属性

作者:互联网

我试图将SelectedItem绑定到视图.但是,当视图位于Resources块中时,该视图将无法访问该视图模型.
当将数据上下文重新分配给子级时,绑定适用于文本块,但不适用于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>

解决方法:

更新3
由于您在NoteView中使用MvvmLight :,请尝试更改

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用作弹出窗口的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>

标签:mvvm-light,wpf,c,mvvm
来源: https://codeday.me/bug/20191208/2095161.html