【问题标题】:How to access the right datacontext如何访问正确的数据上下文
【发布时间】:2015-03-23 15:33:08
【问题描述】:

我正在使用 HierarchicalDataTemplates 构建树视图,并希望扩展一些节点。节点有一个属性“IsNodeExpanded”,我想将属性 IsExpanded 绑定到。

我遇到麻烦的地方是绑定到这个属性。例如。这个

<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="IsExpanded"
            Value="{Binding DataContext.IsNodeExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}">
    </Setter>
</Style>

将绑定到我的 MainViewModel 上定义的属性 IsNodeExpanded 而这

<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="IsExpanded"
            Value="{Binding IsNodeExpanded}">
    </Setter>
</Style>

根本不会有任何效果,因为我猜是绑定存在数据上下文问题。

如何引用正确的数据上下文?

为了完整起见,这是我的 TreeView

 <TreeView ItemsSource="{Binding _questions}">
 <TreeView.Resources>
     <HierarchicalDataTemplate DataType="{x:Type local:Question}"
                               ItemsSource="{Binding Converter={StaticResource QuestionConverter}}">
         <StackPanel Orientation="Horizontal">
             <TextBlock Text="{Binding Path=Name}" />
         </StackPanel>
     </HierarchicalDataTemplate>
     <HierarchicalDataTemplate DataType="{x:Type local:MainOption}"
                               ItemsSource="{Binding MainOptions}">
         <StackPanel Orientation="Horizontal">
             <CheckBox Content="{Binding Path=Name}"
                       IsChecked="{Binding Path=IsSelected}"
                       Command="{Binding DataContext.ToggleSelectedMetaItem, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
                       CommandParameter="{Binding Path=MetaItemId}" />
         </StackPanel>
     </HierarchicalDataTemplate>

 </TreeView.Resources>
 <TreeView.ItemContainerStyle>
     <Style TargetType="{x:Type TreeViewItem}">
         <Setter Property="IsExpanded"
                 Value="{Binding DataContext.IsNodeExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}">
         </Setter>
     </Style>
 </TreeView.ItemContainerStyle>

编辑:

public class MainOption
{
    public string Name { get; set; }
    public int MetaItemId { get; set; }
    public bool IsSelected { get; set; }

    public MainOption()
    {
        this.IsSelected = true;
    }
}

public class Question
{
    public string Name { get; set; }
    public List<MainOption> MainOptions { get; set; }

    public Question()
    {
        MainOptions = new List<MainOption>();
    }
}

【问题讨论】:

  • 你能分享一下 MainOption 和 Question 类或至少属性的定义吗

标签: c# wpf


【解决方案1】:

在 ItemContainerStyle 中,绑定到 IsNodeExpanded 属性时不应定义相对源。如果 itemssource _questions 是问题列表,则 {Binding IsNodeExpanded} 绑定到 Question 类的 IsNodeExpanded 属性。我怀疑你错过了房产。

这里是 xaml:

<TreeView ItemsSource="{Binding Questions}">
    <TreeView.Resources>
        <DataTemplate x:Key="OptionTemplate" DataType="l:MainOption">
            <CheckBox IsChecked="{Binding IsSelected}" Content="{Binding Name}" />
        </DataTemplate>
    </TreeView.Resources>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="l:Question" ItemsSource="{Binding MainOptions}"
                                ItemTemplate="{StaticResource OptionTemplate}" ItemContainerStyle="{x:Null}">
            <!-- DataContext of type Question -->
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded" Value="{Binding IsNodeExpanded}" />
        </Style>
    </TreeView.ItemContainerStyle>

</TreeView>

和 C# 代码:

public class MainWindowViewModel : BindableBase
{
    public MainWindowViewModel()
    {
        Questions = Enumerable.Range(1, 10)
            .Select(i => new Question
            {
                Name = "Question " + i,
                MainOptions = Enumerable.Range(1, 5)
                    .Select(j => new MainOption {Name = "Option " + i})
                    .ToList()
            })
            .ToList();
    }

    public List<Question> Questions { get; private set; }
}

public class Question
{
    public string Name { get; set; }
    public List<MainOption> MainOptions { get; set; }
    public bool IsNodeExpanded { get; set; }

    public Question()
    {
        IsNodeExpanded = true;
        MainOptions = new List<MainOption>();
    }
}

关键是,您在三视图中设置根项目的 Style 和 ItemTemplate。在 HierarchicalItemTemplate 中,ItemSource 用于生成子项,ItemContaierStyle 影响子项的样式,ItemTemplate 影响子项的数据模板

【讨论】:

  • 嗨 Liero,请参阅我上面的编辑。不幸的是,“{Binding Path=IsSelected}”没有效果。
  • 但是,当我键入 {Binding DataContext. }..
  • 你犯了很多错误。给我5分钟重写它。它会比描述它更快
  • 非常感谢您的努力!
猜你喜欢
  • 2020-11-17
  • 1970-01-01
  • 2017-09-24
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2014-12-02
  • 1970-01-01
相关资源
最近更新 更多