WPF Barevný Listbox   zodpovězená otázka

WPF

Dobrý den. Chtěl bych se zeptat jestli je možno v listboxu určité prvky (prvních x) mít v nějaké barvě a ostatní v jíné?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Něco tak primitivního jde i ve Windows Forms, takže odpověď je ano.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Pokud je x nějaké rozumné číslo, můžete použít AlternationCount vlastnost na ListBoxu a nastylovat jednotlivé položky podle toho, který AlternationIndex jim odpovídá. AlternationCount se používá například pro to, aby se každá druhá (pátá, šestá, sedmistá, ...) položka obarvila jinak, než ostatní. Zde bude potřeba použít malý trik, kdy se nastaví AlternationCount na hodnotu Integer.MaxValue (AlternationCount je typu Int32), aby nedošlo k opakování celého vzoru od začátku.

<Window Title="AlternationCount" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="SandboxWpfCs.MainWindow">
  <ListBox AlternationCount="{x:Static sys:Int32.MaxValue}">
    <ListBox.Resources>
      <Style TargetType="{x:Type ListBoxItem}">
        <Style.Triggers>
          <Trigger Property="ItemsControl.AlternationIndex" Value="0">
            <Setter Property="Foreground" Value="Red" />
          </Trigger>
          <Trigger Property="ItemsControl.AlternationIndex" Value="1">
            <Setter Property="Foreground" Value="Red" />
          </Trigger>
          <Trigger Property="ItemsControl.AlternationIndex" Value="2">
            <Setter Property="Foreground" Value="Red" />
          </Trigger>
          <Trigger Property="ItemsControl.AlternationIndex" Value="3">
            <Setter Property="Foreground" Value="Red" />
          </Trigger>
        </Style.Triggers>
      </Style>
    </ListBox.Resources>
    <ListBoxItem>1</ListBoxItem>
    <ListBoxItem>2</ListBoxItem>
    <ListBoxItem>3</ListBoxItem>
    <ListBoxItem>4</ListBoxItem>
    <ListBoxItem>5</ListBoxItem>
    <ListBoxItem>6</ListBoxItem>
  </ListBox>
</Window>

V ukázce obarvují první čtyři položky. Jak vidíte, je tam Trigger pro každý index, který chcete obarvit a proto je dobré, aby počet odlišených položek nebyl vysoký, jinak by styl velmi nabobtnal.

Zdroje

http://msdn.microsoft.com/en-us/library/... - AlternationCount na MSDN

http://joyfulwpf.blogspot.cz/2009/07/dif... - Ukázka použití AlternationCount

http://stackoverflow.com/questions/17372... - Vlákno k tématu na StackOverflow (komentáře u odpovědi)

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Děkuji za řešení. Nicméně můj problém to neřěší zapoměl jsem napsat že x neznám a získám jej až v průběhu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

V tom případě nabízím alternativní řešení, ačkoliv si nejsem jistý, jestli je úplně elegantní. Pravděpodobně by se to dalo udělat lépe, případně mě někdo jistě opraví.

1.) Vytvořte si třídu AlternationIndexToBooleanConverter

Public Class AlternationIndexToBooleanConverter
  Implements IMultiValueConverter

  Public Function Convert(values() As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert
    Dim limit As Integer
    If values.Length = 2 AndAlso TypeOf values(0) Is ListBoxItem AndAlso Integer.TryParse(values(1), limit) Then
      Dim index = ItemsControl.GetAlternationIndex(DirectCast(values(0), ListBoxItem))
      Return index <= limit
    End If
    Return False
  End Function

  Public Function ConvertBack(value As Object, targetTypes() As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack
    Return Enumerable.Empty(Of Object)()
  End Function

End Class

2.)Přidejte tento Converter to Application.xaml:

<Application StartupUri="MainWindow.xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:..." xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Application">
  <Application.Resources>
    <local:AlternationIndexToBooleanConverter x:Key="AlternationIndexToBooleanConverter" />
  </Application.Resources>
</Application>

Jmenný prostor xmlns:local si přepiště na jmenný prostor, kde se nachází ta třída converteru. U mně to je clr-namespace:SandboxWpfVb, protože jsem třídu nedal do žádného speciálního jmenného prostoru a globální namespace je nastaven na SandboxWpfVb. U Vás to může být třeba MyAwesomeProject.Converters.

3.) A pak už jen použití:

<Window DataContext="3" Height="320" Width="240" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:system="clr-namespace:System;assembly=mscorlib"  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="MainWindow">
  <ListBox AlternationCount="{x:Static system:Int32.MaxValue}">
    <ListBox.Resources>
      <Style TargetType="{x:Type ListBoxItem}">
        <Style.Triggers>
          <DataTrigger Value="True">
            <DataTrigger.Binding>
              <MultiBinding Converter="{StaticResource AlternationIndexToBooleanConverter}">
                <Binding RelativeSource="{RelativeSource Mode=Self}" />
                <Binding Path="DataContext" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
              </MultiBinding>
            </DataTrigger.Binding>
            <Setter Property="Foreground" Value="Red" />
          </DataTrigger>
        </Style.Triggers>
      </Style>
    </ListBox.Resources>
    <ListBoxItem Content="1" />
    <ListBoxItem Content="2" />
    <ListBoxItem Content="3" />
    <ListBoxItem Content="4" />
    <ListBoxItem Content="5" />
    <ListBoxItem Content="6" />
    <ListBoxItem Content="7" />
  </ListBox>
</Window>

Jak jistě vidíte, funguje to tak, že DataTrigger dostane MultiBinding, který je vyhodnocovaný naším Converterem. Ten dostane několik hodnot, zkontroluje jejich rozsahy (2 hodnoty, jednou ListBoxItem a pak číslo) a zjistí index položky v ListBoxu. Vrácený výsledek je pak porovnání indexu vůči limitu. ListBox musí mít nastavený AlternationCount (zase na Integer.MaxValue), jinak indexy budou vždy 0 a obarví se Vám vše. Limit, tedy druhá hodnota do Converteru je nastaven na DataContext okna, ale je možné ho nastavit na cokoliv jiného (typicky na nějakou vlastnost DataContextu místo celého DataContextu).

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Děkuji za řešení mého problému.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback