【问题标题】:Unable to access viewmodel properties from inside Listvew.Resources无法从 Listview.Resources 内部访问视图模型属性
【发布时间】:2010-12-03 18:24:02
【问题描述】:

我正在尝试将 SelectedItem 绑定到视图。但是当视图位于 Resources 块内时,视图无法访问视图模型。 当 datacontext 重新分配给子项时,绑定适用于文本块,但不适用于 UserControl (NoteView)

我是否缺少任何绑定?

PFB 修改(整个)代码和内联 cmets。

<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>

笔记视图:

<Grid>
    <TextBlock Text="{Binding Title}" /> // This Text is not displayed
</Grid>

【问题讨论】:

  • 您是指弹出窗口中的绑定不起作用吗?
  • @pivotnig:不,NoteView 中的那个。检查我的内联 cmets。
  • 两个快速的想法:你会不会碰巧覆盖用户控件中的数据上下文,它发生在我身上一次并花了一些时间来发现我的错误:) 另外,你可能已经检查过了,但是你看到了吗Visual Studio 输出窗口中的任何绑定错误?
  • 嗨,亚历克斯!我没有覆盖我的数据上下文。如果我在我的 ListView 之外使用 NoteView,它会起作用。不,我也没有看到任何绑定错误。

标签: c# wpf mvvm mvvm-light


【解决方案1】:

更新 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>

【讨论】:

  • 嗨,Meleak,您提供的解决方案无效。不幸的是,UserControl(NoteView) 无法使用 SelectedNote。我已经编辑了我的问题。请检查我的内联 cmets。
  • @Veer:你的问题有什么进展吗?你试过我的故障排除方法了吗?
  • @Meleak:选择更改时未达到 DataContextChangedHandler。当 NoteView 在列表视图之外时,它可以工作。
  • @Veer:更新了我的答案。几分钟前遇到了类似的问题,这有效
  • @Meleak: Fruitless:( 你能重现这个问题吗?你需要更多代码吗?
【解决方案2】:

不要直接插入 NoteView 并绑定 DataContext,而是使用 ContentPresenter:

<ContentPresenter Content="{Binding SelectedNote}>
    <ContentPresenter.ContentTemplate>
       <DataTemplate>
           <v:NoteView />
       </DataTemplate>
   </ContentPresenter.ContentTemplate>
</ContentPresenter>

【讨论】:

  • 嘿史蒂夫,又是 gr8 2 c u。我在视图周围使用 进行了尝试。但它没有用。
  • @veer 我现在不在电脑旁,所以无法测试,但您可能需要使用 ContentControl 而不是 ContentPresenter
  • 它没有用。
  • 忘记用户控件。即使在 TextBlock 中,我也无法访问 SelectedNote(检查我的代码)。只有在堆栈面板中设置 DataContext 才能访问。
猜你喜欢
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多