【问题标题】:Set Datacontext of an ItemTemplate explicitly显式设置 ItemTemplate 的 Datacontext
【发布时间】:2016-01-14 21:19:47
【问题描述】:

我在下面有以下代码。 WordListObservableCollectionWord 的。

我想要完成的事情是将每个项目的DataContext 设置为包装类NewWordViewModel,而不是默认设置的Word 对象。 CorrespondingWordNewWordViewModel 的依赖属性。

问题是 xaml 代码创建了一个NewWordViewModel 并将其设置为DataContext,但没有将CorrespondingWord 属性设置为实际的Word 对象。

是否有设置此属性的 xaml 方式?

<ItemsControl ItemsSource="{Binding WordList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ui:NewWord>
                <ui:NewWord.DataContext>
                    <viewModels:NewWordViewModel CorrespondingWord="{Binding}"/>
                </ui:NewWord.DataContext>
            </ui:NewWord>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

【问题讨论】:

  • CorrespondingWord 属性移动到NewWord 控件并删除NewWordViewModel 不是更简单吗?
  • 好的,如果我将 NewWordViewModel 的所有内容移动到 NewWord 包括命令,这将有效。但是,我现在如何为命令编写测试? ViewModel 的目的是解耦类并启用单元测试。

标签: c# wpf xaml data-binding datacontext


【解决方案1】:

您可以使用代理在每个项目中保存隐式DataContext,并将绑定设置为正常,如下所示:

<ItemsControl ItemsSource="{Binding WordList}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Border>
         <Border.Resources>
           <DiscreteObjectKeyFrame x:Key="proxy" Value="{Binding}"/> 
         </Border.Resources>
         <ui:NewWord>
           <ui:NewWord.DataContext>
             <viewModels:NewWordViewModel 
                    CorrespondingWord="{Binding Value, Source={StaticResource proxy}}"/>
           </ui:NewWord.DataContext>
         </ui:NewWord>
      </Border>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

【讨论】:

  • 我收到以下错误:Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:(no path); DataItem=null; target element is 'DiscreteObjectKeyFrame' target property is 'Value' (type 'Object')。如果我使用来自this 链接的BindingProxy 类,从FrameworkElement 继承而不是Freezable,它不会输出错误,但UI 上的所有字段都是空的。有没有办法调试哪些依赖属性没有设置?
  • 实际上x:Key="proxy" Value="{Binding}"部分的绑定不起作用。如果我写Value="Some Text" 并使用&lt;TextBlock Text="{Binding Value, Source={StaticResource proxy}}"/&gt; 创建一个TextBlock,它确实会在屏幕上显示Some Text
  • @qqww2 看我的编辑,实际上代理应该放在根视觉的Resources,而不是DataTemplate's Resources
  • 当我覆盖EndInit 方法并查看Tag 值时,它始终是null。我尝试将另一个依赖属性添加到NewWord 类并绑定到它而不是Tag,它给出了相同的结果。但是,当我创建一个附加属性时,它会成功绑定到它。我实际上并不理解这种行为。我希望依赖属性会在 EndInit 方法之前绑定。
  • 实际上,如果DiscreteObjectKeyFrameNewWord 中定义,它会触发一个链。首先它将Value 设置为Word 对象,然后创建新的数据上下文并为其赋予值。更改数据上下文后,DiscreteObjectKeyFrame 上的 Value 更新为 NewWordViewModel,依此类推。在NewWord 周围创建一个边框并将DiscreteObjectKeyFrame 放到边框的资源中可以解决此问题。
猜你喜欢
  • 2011-06-19
  • 1970-01-01
  • 2010-12-03
  • 2013-12-26
  • 2018-07-02
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多