开发者

styling nth item in listview?

I have an external 'current' property (int) which represents the current index of a collection. I have a listview t开发者_StackOverflow社区hat displays this collection. I want to be able to style the 'nth' item of the collection depending on the value of 'current', i.e. if current is 3, highlight the 4th item in the collection (index = 3), etc. How can I do this?

An alternative would be to bind when the item text is equal to another external property.


To customize the style of a ListView, you can create a DataTrigger that binds to a property of the View's DataContext to alter the current style. In this example the code alters the Background.

<ListView.ItemContainerStyle>
  <Style TargetType="ListViewItem">
    <Setter Property="Background" Value="Aqua"/>
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=DataContext.StyleType, RelativeSource={RelativeSource Self}}" Value="1">
          <Setter Property="Background" Value="Chartreuse"/>
        </DataTrigger>
      </Style.Triggers>
  </Style>
</ListView.ItemContainerStyle>

I've added most of the code here so you can get as complete picture as possible of what is happening, but I skipped the common MVVM base classes.

How it works:

  1. ListView ItemsSource binds to Customers
  2. ListView SelectedItem binds to Customer
  3. ListView.ItemContainerStyle has a DataTrigger that binds to DataContext.StyleType
  4. DataContext is a List of Customer objects with a user defined StyleType property that gets initialized in the code-behind
  5. A Button Command clears the value of StyleType
  6. Clicking a row changes the style of the next row
  7. Customer implements INotifyPropertyChanged, that fires when StyleType changes
  8. DataTrigger alters the Background each ListViewItem

Here is the XAML, look at DataTrigger:

<Window x:Class="ListViewScrollPosition.Views.ScrollBarwindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Style on Model" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListView 
            Grid.Row="0"
            SelectedItem="{Binding Customer}"
            ItemsSource="{Binding Customers}" x:Name="myListView">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    <Setter Property="Background" Value="Aqua"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=DataContext.StyleType, RelativeSource={RelativeSource Self}}" Value="1">
                            <Setter Property="Background" Value="Pink"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="First Name"
                                    DisplayMemberBinding="{Binding FirstName}" />
                    <GridViewColumn Header="Last Name"
                                    DisplayMemberBinding="{Binding LastName}" />
                    <GridViewColumn Header="Style Type"
                                    DisplayMemberBinding="{Binding StyleType}" />
                </GridView>
            </ListView.View>
        </ListView>
        <Button Grid.Row="1" Content="Change Style" Command="{Binding Path=AlterStyle}"/>
    </Grid>
</Window>

Here is the ViewModel the View uses to get Customers and to alter the value of StyleType:

using System.Collections.Generic;
using System.Windows.Input;
using ListViewScrollPosition.Commands;
using ListViewScrollPosition.Models;

namespace ListViewScrollPosition.ViewModels
{
 public class MainViewModel : ViewModelBase
 {
   private DelegateCommand _alterStyleCommand;

   public MainViewModel()
   {
   }

   public ICommand AlterStyle
   {
     get
     {
       if (_alterStyleCommand == null)
        {
          _alterStyleCommand = new DelegateCommand(AlterStyleCommand);
        }
       return _alterStyleCommand;
     }
   }

   private void AlterStyleCommand()
   {
    foreach (var customer in Customers)
    {
      customer.StyleType = 0;
    }
   }

   private void ApplyStyleToNextRow(Customer currentCustomer)
   {
     bool setNext = false;
     foreach (var customer in Customers)
     {
       if (setNext)
       {
         customer.StyleType = 1;
         setNext = false;
       }
       else
       {
         customer.StyleType = 0;
       }

       if (currentCustomer == customer)
       {
         setNext = true;
       }
     }
   }

   private List<Customer> _customers = Customer.GetSampleCustomerList();
   public List<Customer> Customers
   {
     get
     {
        return _customers;
     }
   }

   private Customer _customer = null;
   public Customer Customer
   {
     get
     {
       return _customer;
     }
     set
     {
       _customer = value;
       ApplyStyleToNextRow(_customer);
       OnPropertyChanged("Customer");
     }
   }
 }
}

Here is the Model, ViewModelBase implements INotifyPropertyChanged, StyleType fires OnPropertyChanged when changed which updates each ListViewItem:

using System;
using System.Collections.Generic;

namespace ListViewScrollPosition.Models
{
  public class Customer : ViewModels.ViewModelBase
  {
    public String FirstName { get; set; }
    public String LastName { get; set; }

    private int _style;
    public int StyleType
    {
      get { return _style;}
      set
      {
        _style = value;
        OnPropertyChanged("StyleType");
      }
    }

    public Customer(String firstName, String lastName, int styleType)
    {
      this.FirstName = firstName;
      this.LastName = lastName;
      this.StyleType = styleType;
    }

    public static List<Customer> GetSampleCustomerList()
    {
     return new List<Customer>(new Customer[4] {
            new Customer("A.", "Zero", 0), 
            new Customer("B.", "One", 1),
            new Customer("C.", "Two", 2),
            new Customer("D.", "Three", 1)
        });
    }
  }
}

Here is the code-behind where I setup the DataContext:

using System.Windows;
namespace ListViewScrollPosition.Views
{
  public partial class ScrollBarwindow : Window
  {
    public ScrollBarwindow()
    { 
      InitializeComponent();
      DataContext = new ViewModels.MainViewModel();
    }
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜