2013-07-05 3 views
1

Я в странной ситуации. Я создаю список элементов, сгруппированных по определенным категориям. В моей модели зрения у меня есть элементы, хранящиеся в экземпляре ReadOnlyDictionary<string, List<CustomObject>>, где CustomObject представляет класс, который я создал для хранения каждого элемента списка. Строка - это категория. На мой взгляд, у меня есть StackPanel с <ItemsControl> внутри него. Контроль пунктов имеет ItemTemplate, какой вид выглядит следующим образом:Wpf tempating - Как получить доступ к родительскому элементу элемента ItemsControl?

<DataTemplate x:Key="DataTemplateName"> 
    <StackPanel> 
     <Separator /> 
     <TextBlock Text="{Binding Key}" /> 
     <ItemsControl ItemsSource="{Binding Value}" /> 
    </StackPanel> 
</DataTemplate> 

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

Я пробовал использовать ItemTemplateSelector, но проблема в том, что он имеет доступ только к текущему элементу, поэтому он не знает, находится ли он в первом элементе. Я также пытался делать что-то вроде

<Separator 
    Visibility={Binding ShowSeparator, RelativeSource={RelativeSource AncestorType={x:Type CustomObject}}}" /> 

... где ShowCategories свойство зависимостей в классе CustomObject, который смотрит на ReadOnlyDictionary инстанции и говорит ли или не показывать разделители. Но ShowCategories никогда не открывается, когда я это делаю. Я думаю, что даже если бы это было так, у него не было бы способа узнать, какой элемент его вызывает.

So. Что я делаю?

+0

Вы можете добавить DataTrigger в стиль Separator, который скроет разделитель, если выбран первый элемент. –

ответ

0

Я бы с MVVM подход:

  1. Иметь CustomObjectViewModel хранится в вместо вашего словаря вашего CustomObject, с CustomObject, как это модель.

  2. В CustomObjectViewModel есть доступ к CustomObjectService (или ссылка на словарь для простоты).

  3. В упомянутой службе, есть способ, аналогичный:

    Public Boolean IsCustomObjectFirst(CustomObjectViewModel vm){..}

    Это будет, очевидно, проверьте положение данного элемента.

  4. теперь просто имеют свойство ShouldDisplaySeperator в вашем CustomObjectViewModel, что получит это значение от CustomObjectService.IsCustomObjectFirst(this)

  5. теперь просто использовать его в определении вашей точки зрения, используя что-то похожее на:

    Смотреть Определение:

    <DataTemplate x:Key="DataTemplateName"> 
        <StackPanel> 
         <Separator Visibilty="{Binding ShouldDisplaySeperator,Converter={StaticResource BooleanToVisibilityConverter}}" /> 
         <TextBlock Text="{Binding Model.Key}" /> 
         <ItemsControl ItemsSource="{Binding Model.Value}" /> 
        </StackPanel> 
    </DataTemplate> 
    
+0

Спасибо! Я попробую! –

+0

Не проблема, решила ли ваша проблема? или требуется ли настройка ответа? –

+0

У меня сейчас есть шанс попробовать. Я дам Вам знать. –

0

Вы со uld делать это без необходимости добавления новых свойств в вашу виртуальную машину или с помощью ItemTemplateSelector.

Я бы предпочел, чтобы держать это в одиночку XAML, как это просто вид родственный и ничего общего с какой-либо логики, которая нуждается в «проверке»

Так XAML решение могло бы использовать ItemsControl.AlternationIndex

что-то например:

<ListBox AlternationCount="{Binding RelativeSource={RelativeSource Self}, Path=ItemsSource.Count, Mode=OneWay}"> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <StackPanel> 
     <Separator x:Name="seperator" /> 
     <TextBlock Text="{Binding Key}" /> 
     <ItemsControl ItemsSource="{Binding Value}" /> 
     </StackPanel> 
     <DataTemplate.Triggers> 
     <DataTrigger Binding="{Binding Path=(ListBox.AlternationIndex), 
             RelativeSource={RelativeSource FindAncestor, 
                     AncestorType={x:Type ListBoxItem}}}" 
         Value="0"> 
      <Setter TargetName="seperator" 
        Property="Visibility" 
        Value="Hidden" /> 
     </DataTrigger> 
     </DataTemplate.Triggers> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

2 ключевых части к этому фрагменту.

  • сопоставит AlternationCount на ListBox то же самое, как ItemSource.Count, чтобы таким образом генерировать уникальный AlternationIndex на каждый ListBoxItem.
  • DataTemplate.DataTrigger просто проверяет текущий элемент, чтобы увидеть, является ли оно AlternationIndex равно 0, и если он скрывает seperator.
Смежные вопросы