绑定到祖先treenode的datacontext属性

时间:2013-11-29 09:27:46

标签: c# wpf treeview

我的TreeView结构定义如下:

<TreeView ItemsSource="{Binding RootCollection}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
            <TextBlock Foreground="Green" Text="{Binding Text}" />
            <HierarchicalDataTemplate.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
                    <TextBlock Foreground="Black" Text="{Binding Text}" />
                </HierarchicalDataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

你可以看到根元素有green前景,所有子元素都是black 现在我想在父母将“black”属性设置为true的子节点上将子节点的前景颜色从red更改为Failed

例如,如果RootCollection[0].Failed = true,则树视图上的所有RootCollection[0].ChildNodes都应变为red(rootnode保持green,并且在这种情况下不会有任何孙子节点,因此它不会不管他们会发生什么事。)

我尝试在任何可能的地方设置DataTrigger样式并尝试以多种方式绑定到RelativeSource,但我无法处理它。

任何帮助将不胜感激:)


DataContext是这样的:

public class MyTreeNode : INotifyPropertyChanged
{
private string text;
private ObservableCollection<MyTreeNode> childNodes;
private bool failed;

public string Text
{
    get
    {
        return this.text;
    }
    set 
    {
        this.text = value;
        Changed("Text");
    }
}

public bool Failed
{
    get
    {
        return this.failed;
    }
    set
    {
        this.failed = value;
        Changed("Text");
    }
}

public ObservableCollection<MyTreeNode> ChildNodes
{
    get
    {
        return this.childNodes;
    }
    set
    {
        this.childNodes = value;
        Changed("ChildNodes");
    }
}

private void string Changed(string propertyName)
{
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public ObservableCollection<MyTreeNode> RootCollection { get; set; }

public MyClass()
{
    this.RootCollection = new ObservableCollection<MyTreeNode>
    {
        new MyTreeNode
        {
            Text = "first",
            Failed = true,
            ChildNodes = new ObservableCollection<MyTreeNode>
            {
                new MyTreeNode { Text = "first first" },
                new MyTreeNode { Text = "first second" }
            }
        },
        new MyTreeNode
        {
            Text = "second",
            ChildNodes = new ObservableCollection<MyTreeNode>
            {
                new MyTreeNode { Text = "second first" }
            }
        }
    };
}

它被简化了,因为我的真实代码使用了许多自定义类。

以下是Snoop的视图结构:

http://i.imgur.com/XMF6rLN.png

(我需要根据标记为红色的属性设置标记为蓝色的属性)

2 个答案:

答案 0 :(得分:0)

我无法检查此刻是否有效,所以可能没有,但它看起来是正确的。试试这个:

<HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
    <TextBlock Text="{Binding Text}">
        <TextBlock.Style>
            <Style>
                <Setter Property="Foreground" Value="Black" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Failed, RelativeSource={
RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=1}}" Value="True">
                        <Setter Property="Foreground" Value="Red" />
                    </DataTrigger> 
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</HierarchicalDataTemplate>

如果它不起作用,您可以尝试使用AncestorLevel属性,将其设置为2或3,甚至删除它。让我知道它是怎么回事。

答案 1 :(得分:0)

您可以使用模板选择器

//你把它放在你的App.xaml

  <Application.Resources>
     <HierarchicalDataTemplate x:Key="failed" ItemsSource="{Binding ChildNodes}">
        <TextBlock Name="pTxt" Foreground="Red" Text="{Binding Text}" >
        </TextBlock>
        <HierarchicalDataTemplate.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
                <TextBlock Foreground="Black" Text="{Binding Text}" />
            </HierarchicalDataTemplate>
        </HierarchicalDataTemplate.ItemTemplate>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate x:Key="succeded" ItemsSource="{Binding ChildNodes}">
        <TextBlock Name="pTxt" Foreground="Green" Text="{Binding Text}" >
        </TextBlock>
        <HierarchicalDataTemplate.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
                <TextBlock Foreground="Black" Text="{Binding Text}" />
            </HierarchicalDataTemplate>
        </HierarchicalDataTemplate.ItemTemplate>
    </HierarchicalDataTemplate>
</Application.Resources>

//在你的Window.cs中

 public class ResourceInstDataTemplateSelector : DataTemplateSelector
 {
     public override DataTemplate
         SelectTemplate(object item, DependencyObject container)
    {
         FrameworkElement element = container as FrameworkElement;

        if (element != null && item != null && item is MyTreeNode)
        {
            MyTreeNode treeNode = item as MyTreeNode;
            DataTemplate temp = null;
            if (treeNode.Failed)
                temp = App.Current.Resources["failed"] as HierarchicalDataTemplate;                
            else
                temp = App.Current.Resources["succeded"] as HierarchicalDataTemplate;

            return temp;
        }

        return null;
    }
}

//这个在你的window.xaml.cs

 <TreeView Name="treeView" ItemsSource="{Binding RootCollection}">
        <TreeView.ItemTemplateSelector>
            <myApp:ResourceInstDataTemplateSelector></myApp:ResourceInstDataTemplateSelector>
        </TreeView.ItemTemplateSelector>



    </TreeView>

我试过了,它完美地工作了 希望这个帮助