Question

I have create a DataTemplate for my Component object. I added DataTrigger to determine if the component should be visible or not. Essentially we have filters and the code checks those filters to determine if the component should be Visible or Collapse. The issue I have is that I want the trigger to set the visibility to "Collapse" or "Visible" of the parent container, i.e a ListBoxItem. The code works but sets it at the Border instead.

The template starts like this:

   <DataTemplate DataType="{x:Type local:Component}">
                <Border .....

I am providing the code for my Trigger and I'll explain what I tried below without success.

        <DataTemplate.Triggers>
            <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource TrueWhenComponentIsVisible}">
                        <Binding Path="Type" />
                        <Binding Path="Dependency"/>
                        <Binding Path="SelectedType" RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}"/>
                        <Binding Path="SelectedDepencency" RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}"/>
                    </MultiBinding>
                </DataTrigger.Binding>
                <DataTrigger.Setters>
                    <Setter Property="Visibility" Value="Visible"></Setter>
                </DataTrigger.Setters>
            </DataTrigger>

            <DataTrigger Value="False">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource TrueWhenComponentIsVisible}">
                        <Binding Path="Type" />
                        <Binding Path="Dependency"/>
                        <Binding Path="SelectedType" RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}"/>
                        <Binding Path="SelectedDepencency" RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}"/>
                    </MultiBinding>
                </DataTrigger.Binding>
                <DataTrigger.Setters>
                    <Setter Property="Visibility" Value="Collapsed"></Setter>
                </DataTrigger.Setters>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>

For the Setter Property

<Setter Property="Visibility" Value="Collapsed"></Setter>

I attempted to use the binding to get the listboxitem like this:

 <Setter Property="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}, Path=Visibility}" Value="Collapsed"></Setter>

I get this error when I try to run it, so I assume I can't use binding there at all and need a different approach?

A 'Binding' cannot be set on the 'Property' property of type 'Setter'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject
Was it helpful?

Solution

Worked for me.
Don't know why it did not work for you?

<ListBox x:Name="lb" ItemsSource="{Binding}" DisplayMemberPath="Text">
    <ListBox.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="Visibility" Value="{Binding Path=Vis}" />
        </Style>
    </ListBox.Resources>
</ListBox>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.DataContext = this;
        InitializeComponent();
        List<TextVis> TextViss = new List<TextVis>();
        TextVis tv1 = new TextVis();
        tv1.Text = "tv1";
        tv1.Vis = System.Windows.Visibility.Hidden;
        TextViss.Add(tv1);
        TextVis tv2 = new TextVis();
        tv2.Text = "tv2";
        tv2.Vis = System.Windows.Visibility.Visible;
        TextViss.Add(tv2);
        lb.ItemsSource = TextViss;
    }
    public class TextVis
    {
        public string Text { get; set; }
        public Visibility Vis { get; set; }
    }
}

OTHER TIPS

I want the trigger to set the visibility to "Collapse" or "Visible" of the parent container, i.e a ListBoxItem

Change the ItemContainerStyle, like this:

<ListBox ...>
   <ListBox.ItemContainerStyle>
      <Style TargetType="ListBoxItem">
         <Style.Triggers>

             <DataTrigger Value="True">
                <DataTrigger.Binding>
                    <MultiBinding Converter="{StaticResource TrueWhenComponentIsVisible}">
                        <Binding Path="Type" />
                        <Binding Path="Dependency"/>
                        <Binding Path="SelectedType" RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}"/>
                        <Binding Path="SelectedDepencency" RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}"/>
                    </MultiBinding>
                </DataTrigger.Binding>

                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </ListBox.ItemContainerStyle>
</ListBox>

BTW, you should really create a proper ViewModel and move all this logic to the ViewModel level instead of so much MultiBinding and Converter-based stuff.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top