根据TreeViewItem的属性更改WPF UserControl

时间:2013-06-12 06:40:11

标签: wpf enums selecteditem datatrigger

我的应用程序在左侧显示了一个TreeView,其中的分层有序项目都是相同的类型。所有项都有一个依赖属性,可以有两个值之一。该值是枚举。根据此值,我想在左侧显示两个UserControl之一。我的想法是插入两个控件并将它们的不透明度设置为0.然后我想插入一个带有DataTrigger的Style,它根据枚举值触发不透明度。但我无法从其他控件的DataTrigger访问一个控件的属性;并且触发器似乎无法识别枚举的值。

枚举:

public enum IdentityType
{
    Person,
    OrganisationUnit
}

XAML:

<TreeView Grid.Column="0" Grid.Row="1" Background="AntiqueWhite" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Identities}" x:Name="OiTree">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Childs}">
            <TextBlock Text="{Binding}"/>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

<Controls:UcPerson Grid.Column="1" Grid.Row="1" Opacity="0">
    <Controls:UcPerson.Style>
        <Style TargetType="Controls:UcPerson">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Type, ElementName=OiTree.SelectedItem}" Value="Person">
                    <Setter Property="Opacity" Value="1"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Controls:UcPerson.Style>
</Controls:UcPerson>

<Controls:UcOrgUnit Grid.Column="1" Grid.Row="1" Opacity="0">
    <Controls:UcOrgUnit.Style>
        <Style TargetType="Controls:UcOrgUnit">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Type, ElementName=OiTree.SelectedItem}" Value="OrganisationUnit">
                    <Setter Property="Opacity" Value="1"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Controls:UcOrgUnit.Style>
</Controls:UcOrgUnit>

2 个答案:

答案 0 :(得分:1)

问题是您是先在控件上直接设置Opacity

控件上的显式设置将始终覆盖触发器值。

但是,触发器值将覆盖样式设置器。

以下代码应该有效(虽然我自己没有测试过)

    <Controls:UcPerson Grid.Column="1" Grid.Row="1">
    <Controls:UcPerson.Style>
        <Style TargetType="Controls:UcPerson">
            <Style.Setters>
               <Setter Property="Opacity" Value="0" />
            </Style.Setters>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Type, ElementName=OiTree.SelectedItem}"  Value="Person">
                    <Setter Property="Opacity" Value="1"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Controls:UcPerson.Style>

请在此处查看此问题,以获取问题的另一个示例:DataTrigger not firing

<小时/> 顺便说一句,我相信使用DataTemplateSelector可以更优雅地解决您的问题。

答案 1 :(得分:1)

正如Andrew暗示我的问题的解决方案是DataTemplateSelector。我创建了两个模板并使用了ContentControl,而不是两个userControl。 ContentControl的content属性绑定到TreeView的SelectedItem,我实现了一个简单的DataTemplateSelector,它将内容强制转换为原始对象,决定使用哪个模板。来源(已修改)来自此处:link

这是xaml:

<Window.Resources>
    <DataTemplate x:Key="borderTemplate">
        <Border BorderThickness="1" BorderBrush="Brown" CornerRadius="5">
            <TextBlock Margin="5" Text="Border Template"/>
        </Border>
    </DataTemplate>
    <DataTemplate x:Key="twoTextBlockTemplate">
        <StackPanel>
            <TextBlock Margin="5" Text="First TextBlock"/>
            <TextBlock Margin="5" Text="Second TextBlock"/>
        </StackPanel>
    </DataTemplate>
    <vm:OiContentTemplateSelector
        x:Key="myContentTemplateSelector" 
        BorderTemplate="{StaticResource borderTemplate}"
        TwoTextBlockTemplate="{StaticResource twoTextBlockTemplate}"/>
</Window.Resources>

                                                                                         

这是DataTemplateSelector:

public class OiContentTemplateSelector : DataTemplateSelector
{
    public DataTemplate BorderTemplate
    { get; set; }

    public DataTemplate TwoTextBlockTemplate
    { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        OrganisationIdentity value = item as OrganisationIdentity;

        if (value != null)
        {
            if (value.Type == IdentityType.Person)
                return BorderTemplate;
            else if (value.Type == IdentityType.OrganisationUnit)
                return TwoTextBlockTemplate;
            return base.SelectTemplate(item, container);
        }
        else
            return base.SelectTemplate(item, container);
    }
}

也许这有助于某人

相关问题