微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WPF UserControl 多个DataContexts?

如何解决WPF UserControl 多个DataContexts?

我目前有一个带有 TreeView 和其他一些东西的用户控件。 TreeView 的 DataContext 设置为 viewmodel 并且绑定有效:

<TreeView Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2"
          ItemsSource="{Binding LoadedItem.Batches}" 
          Background="{Binding UiTools.ContainersBackground}">
  <Interactivity:Interaction.Behaviors>
    <Behaviros:BindableSelectedItemBehavior SelectedItem="{Binding SelectedSessionItem,Mode=TwoWay}"/>
  </Interactivity:Interaction.Behaviors>
  <TreeView.ItemContainerStyle>
    <Style targettype="{x:Type TreeViewItem}">
      <Setter Property="IsExpanded" Value="True"/>
    </Style>
  </TreeView.ItemContainerStyle>
  <TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Groups}">
      <TextBlock Text="{Binding Name,UpdateSourceTrigger=LostFocus}"/>
      <HierarchicalDataTemplate.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Samples}">
          <TextBox Text="{Binding Name}"/>
          <HierarchicalDataTemplate.ItemTemplate>
            <HierarchicalDataTemplate>
              <TextBlock Text="{Binding Name}"/>
            </HierarchicalDataTemplate>
          </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
      </HierarchicalDataTemplate.ItemTemplate>
    </HierarchicalDataTemplate>
  </TreeView.ItemTemplate>
</TreeView>

但现在我正在尝试使用 this 教程使节点可编辑。

在那里,UserControl 使用了一些隐藏的代码,现在它实现了 INotifyPropertyChanged。事件处理程序的定义很简单:

    public event PropertyChangedEventHandler PropertyChanged;

但是使用的时候总是null

public bool IsInEditMode
{
  get { return isInEditMode; }
  set
  {
    isInEditMode = value;
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
      handler(this,new PropertyChangedEventArgs(nameof(IsInEditMode)));
    }
  }
}

在这里,处理程序永远不会被调用,因为它总是空的。

我想这是因为我的 UserControl 的 DataContext 设置为 viewmodel 而不是 UserControl 本身。

当我将 DataContext 设置为 UserControl 时,我将无法将数据绑定到 viewmodels 项。

如何解决这个问题?

解决方法

视图上的每个控件都有自己的 DataContext。默认情况下,它只会继承父 DataContext,但您可以将其显式设置为您想要使用的任何内容:

DataContext={whatever}

或者,在这种情况下更常见的是,您可以使用 ElementName 在绑定本身中指定不同的绑定源。请注意您提到的教程中的绑定:

<Condition Binding="{Binding IsInEditMode,ElementName=wpfTreeViewInPlaceEditControl}" Value="True"/>

ElementName 位表示查看指定元素 (wpfTreeViewInPlaceEditControl) 而不是绑定源的当前 DataContext。

,

事件处理程序为空,因为没有附加委托。
显然,您对此属性的绑定无法解析。

通常,您可以绑定到每个源(必须满足某些限制,例如作为公共属性),而不仅限于 DataContext

您可以指定 Binding.ElementName 将绑定源设置为命名元素或使用 Binding.RelativeSource 遍历可视化树以查找源对象。

在您的情况下,您可以使用 Binding.RelativeSource 来查找 UserControl

{Binding RelativeSource={RelativeSource AncestorType UserControl},Path=IsInEditMode}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。