سؤال

My application shows a TreeView on the left with hierarchical ordered items which are all the same type. All the items have a dependency property which can have one of two values. This value is an enum. Depending on this value I want to show one of two UserControls on the left. My idea was to insert both controls and set their opacity to 0. Then I wanted to insert a Style with a DataTrigger that triggers the opacity depending on the enum's value. But I can not access the properties of one control from the other control's DataTrigger; and the trigger does not seem to recognize the enum's value.

The enum:

public enum IdentityType
{
    Person,
    OrganisationUnit
}

The 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

As Andrew implied the solution to my problem was a DataTemplateSelector. Instead of two userControls I created two templates and Used a ContentControl. The content Property of the ContentControl is bound to the SelectedItem of the TreeView and I implemented a simple DataTemplateSelector which casts the content to the original object an decides wich template to use. The source (modified) is from here: link

This is the 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>

This is the 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);
    }
}

Perhaps this helps somebody

نصائح أخرى

The problem is that you are setting the Opacity directly on the control first.

An explicit setting on a control will always override a trigger value.

However, a trigger value will override a style setter.

The following code should work (though I haven't tested it myself)

    <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>

See this question here for another example of the problem: DataTrigger not firing


As an aside, I believe your problem could be solved more elegantly using a DataTemplateSelector.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top