样式列表视图Selector.SelectedItem

时间:2011-01-28 06:15:01

标签: wpf listview styles

我使用SelectionMode =扩展的ListView和ListViewItem的样式:

MainWindow.xaml:

<Window x:Class="ListViewSelection.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type ListViewItem}">
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Aqua"/>
            </Style.Resources>
            <!--<Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="Aqua" />
                </Trigger>
            </Style.Triggers>-->
        </Style>
    </Window.Resources>
    <StackPanel>
        <ListView Name="MyListView" ItemsSource="{Binding MyList}" SelectionChanged="SelectionChanged" SelectionMode="Extended" />
        <Label Name="MyLabel" />
    </StackPanel>
</Window>

MainWindow.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;

namespace ListViewSelection
{
    public partial class MainWindow : Window
    {

        public ObservableCollection<string> MyList { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
            MyList = new ObservableCollection<string>();
            MyList.Add("Jane");
            MyList.Add("Paul");
            MyList.Add("Sally");
            MyList.Add("Ian");
        }

        private void SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            MyLabel.Content = (sender as ListBox).SelectedItem;
        }
    }
}

这会为所有选定项目设置精细颜色。但我还要设置Selector.SelectedItem的样式,它是选择中的“活动”或第一个项目。这是标签显示的那个。

有任何帮助吗?谢谢!

1 个答案:

答案 0 :(得分:0)

您可以在ViewData类中公开IsFirstInSelection属性(我想你已经拥有它)。

然后你可以放置DataTrigger来监控这样的变化:

        <Style.Triggers>
            <DataTrigger Binding="{Binding IsFirstInSelection}">
                <Setter Property="Background"
                        Value="Blue"/>
            </DataTrigger>
        </Style.Triggers>

同样在你的情况下,我建议避免更改HighlightBrushKey,但通过更改Background属性来实现目标。您还可以在ViewData类中公开IsSelected属性,因此它看起来像这样:

public class ViewData: ObservableObject
{
    private bool _isSelected;
    public bool IsSelected
    {
        get
        {
            return this._isSelected;
        }
        set
        {
            if (this._isSelected != value)
            {
                this._isSelected = value;
                this.OnPropertyChanged("IsSelected");
            }
        }
    }

    private bool _isFirstInSelection;
    public bool IsFirstInSelection
    {
        get
        {
            return this._isFirstInSelection;
        }
        set
        {
            if (this._isFirstInSelection != value)
            {
                this._isFirstInSelection = value;
                this.OnPropertyChanged("IsFirstInSelection");
            }
        }
    }
}

你的风格根据两个属性设置背景:

        <Style x:Key="TreeItemStyle"
               TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected"
                    Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
            <Setter Property="IsFirstInSelection"
                    Value="{Binding Path=IsFirstInSelection}"/>
            <Setter Property="Background"
                    Value="Green"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}"
                             Value="True">
                    <Setter Property="Background" 
                            Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsFirstInSelection}">
                    <Setter Property="Background"
                        Value="Blue"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>

当然,在模型或后面的视图代码中,您应该监视IsSelected属性更改的通知,并根据所选项目设置/重置IsFirstInSelection。

我希望你理解我的想法。

-------编辑--------

首先,我继续坚持你应该开发适当的ViewData类:

public class ViewData : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        var ev = this.PropertyChanged;
        if (ev != null)
        {
            ev(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public ViewData(string name)
    {
        this._personName = name;
    }

    private string _personName;
    public string PersonName
    {
        get
        {
            return this._personName;
        }
        set
        {
            if (this._personName != value)
            {
                this._personName = value;
                this.OnPropertyChanged("PersonName");
            }
        }
    }

    private bool _isFirstSelected;
    public bool IsFirstSelected
    {
        get
        {
            return this._isFirstSelected;
        }
        set
        {
            if (this._isFirstSelected != value)
            {
                this._isFirstSelected = value;
                this.OnPropertyChanged("IsFirstSelected");
            }
        }
    }
}

在处理SelectionChanged事件期间,您应该像这样修改属性IsFirstSelected:

public ObservableCollection<ViewData> MyList { get; set; }
private void SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var lb = sender as ListBox;
    if (lb != null)
    {
        MyLabel.Content = lb.SelectedItem;
        foreach (var item in this.MyList)
        {
            if (item == lb.SelectedItem)
            {
                item.IsFirstSelected = true;
            }
            else
            {
                item.IsFirstSelected = false;
            }
        }
    }
}

但默认的ListViewItem模板不会对Background setter做出反应,因此您应该以样式覆盖其模板:

<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListViewItem">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter Content="{Binding PersonName}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected"
                                Value="True">
                        <Setter Property="Background"
                                Value="Yellow"/>
                    </Trigger>

                    <DataTrigger Binding="{Binding IsFirstSelected}" 
                                    Value="True">
                        <Setter Property="Background" 
                                Value="Aqua" />
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style> 

如果不接受此解决方案,请告诉我。我有一些想法,但现在没有足够的时间在代码中检查它们。