2014-03-07 2 views
1

Я создал DataTemplate для моего объекта Component. Я добавил DataTrigger, чтобы определить, должен ли компонент быть видимым или нет. По существу у нас есть фильтры, и код проверяет эти фильтры, чтобы определить, должен ли компонент быть видимым или свернуть. Проблема заключается в том, что я хочу, чтобы триггер установил видимость «Collapse» или «Visible» из родительского контейнера, то есть ListBoxItem. Код работает, но вместо этого устанавливает его на границе.WPF Как установить видимость родительского контейнера из шаблона данных

Шаблон начинается так:

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

я обеспечиваю код для моего Trigger, и я объясню, что я пытался ниже без успеха.

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

Для Setter Property

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

Я попытался использовать связывание, чтобы получить ListBoxItem так:

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

Я получаю эту ошибку, когда я пытаюсь запустить его, так Я предполагаю, что вообще не могу использовать привязку и нужен другой подход?

A 'Binding' cannot be set on the 'Property' property of type 'Setter'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject 
+0

Я бы рекомендовал исследовать 'ListCollectionView'. Затем ваш «ListBox» может использовать представление в качестве источника и указать фильтры в коде. Это намного чище, чем попытка сделать это на уровне xaml. – Julien

+0

Что не так с настройкой видимости на границе? – Paparazzi

+2

Насколько я знаю, '' Binding' не работает в 'Setter.Property'. Вы должны указать статическое значение в свойстве. –

ответ

2

Работал для меня.
Не знаете, почему это не сработало для вас?

<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; } 
    } 
} 
+0

Проблема со стилем заключается в том, что у меня нет доступа к моим свойствам DataContext. Вот почему я добавил триггер данных. Если вы заметили выше, я написал IMultiValueConverter для определения «True» или «False», если компонент должен показывать – gmang

+1

. Все, что я могу сказать, это работает для меня. – Paparazzi

+0

@AnatoliyNikolaev. Это сработало для меня. – Paparazzi

2

Я хочу, чтобы триггер, чтобы установить видимость «свернуть» или «Видимый» из родительского контейнера, т.е. ListBoxItem

Изменение ItemContainerStyle, как это:

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

Кстати, вы действительно должны создать надлежащую ViewModel и переместить всю эту логику на уровень ViewModel, а не столько MultiBinding и Conv основанный на материалах.

+0

Единственная проблема с предоставленным кодом - я всегда получаю «DepencencyProperty.UnsetValue» в конвертере, знаете ли вы, почему?... и да, я буду реорганизовать использовать ViewModel в конце концов, так что спасибо! – gmang

+1

@gmang Я получил это раньше с MultiBinding Converter. Нет гарантированного заказа на привязку оценки, и иногда конвертер срабатывает до того, как будут установлены свойства. Но, похоже, это не происходит с одним конвертером. Проверьте значение null и назначьте как можно лучше. Много раз он будет возвращаться после конвертации после конверсии. – Paparazzi