如何设置ListView项目的样式,使其不具有圆角,并使其具有所选项目的背景颜色倒置?

时间:2013-07-11 17:49:45

标签: c# wpf listview gridview styling

假设我有以下代码(您可以创建一个新的WPF项目并测试它,只需给默认的Grid名称MainGrid):

namespace WPFTesting
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        ObservableCollection<Message> messages = new ObservableCollection<Message>();

        public MainWindow()
        {
            InitializeComponent();
            messages.Add(new Message(DateTime.Now, "This is a test."));
            messages.Add(new Message(DateTime.Now, "This is a multi-line message.\nThis is a multi-line message."));
            messages.Add(new Message(DateTime.Now, "This is a multi-line message.\nThis is a multi-line message."));
            messages.Add(new Message(DateTime.Now, "This is a multi-line message.\nThis is a multi-line message."));
            messages.Add(new Message(DateTime.Now, "This is a test."));
            messages.Add(new Message(DateTime.Now, "This is a test."));
            messages.Add(new Message(DateTime.Now, "This is a test."));
            messages.Add(new Message(DateTime.Now, "This is a test."));
            ListView listView = new ListView();
            Style style = new Style();
            style.TargetType = typeof(ListViewItem);
            DataTrigger trigger = new DataTrigger();
            trigger.Binding = new Binding("Text");
            trigger.Value = "This is a test.";
            trigger.Setters.Add(new Setter(ListViewItem.BackgroundProperty, Brushes.Pink));
            style.Triggers.Add(trigger);
            style.Setters.Add(new Setter(ListViewItem.HeightProperty, 20.0));
            style.Setters.Add(new Setter(ListViewItem.MarginProperty, new Thickness(0)));
            style.Setters.Add(new Setter(ListViewItem.BorderThicknessProperty, new Thickness(0)));
            listView.ItemContainerStyle = style;
            GridView gridView = new GridView();
            listView.View = gridView;
            GridViewColumn timeStampColumn = new GridViewColumn();
            timeStampColumn.DisplayMemberBinding = new Binding("Date");
            GridViewColumnHeader timeStampHeader = new GridViewColumnHeader();
            timeStampHeader.Content = "Time";
            timeStampColumn.Header = timeStampHeader;
            gridView.Columns.Add(timeStampColumn);
            GridViewColumn messageColumn = CreateGridViewColumn("Message", "Text");
            gridView.Columns.Add(messageColumn);
            Binding binding = new Binding();
            binding.Source = messages;
            listView.SetBinding(ItemsControl.ItemsSourceProperty, binding);
            MainGrid.Children.Add(listView);
        }

        private static GridViewColumn CreateGridViewColumn(string header, string bindingPath)
        {
            GridViewColumn gridViewColumn = new GridViewColumn();
            gridViewColumn.Header = new GridViewColumnHeader() { Content = header };
            string xaml = @"
            <DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""> 
              <StackPanel Orientation=""Horizontal"">
                <TextBlock Text=""{Binding Text}"" MaxHeight=""20"">
                  <TextBlock.ToolTip>
                    <TextBlock Text=""{Binding Text}""/>
                  </TextBlock.ToolTip>
                </TextBlock>
              </StackPanel>
            </DataTemplate>";
            StringReader stringReader = new StringReader(xaml);
            XmlReader xmlReader = XmlReader.Create(stringReader);
            gridViewColumn.CellTemplate = XamlReader.Load(xmlReader) as DataTemplate;

            return gridViewColumn;
        }

        public class Message
        {

            public Message(DateTime aDate, String aText)
            {
                Date = aDate;
                Text = aText;
            }

            public DateTime Date { get; set; }
            public String Text { get; set; }
        }
    }
}

请注意,在粉色线条之间,ListViewItems具有轻微的圆角。如何删除此效果?

此外,行选择并不是那么明显,因为我删除了边框粗细。如何使行选择更明显?我正在考虑反转背景颜色,但这可能不是一个好主意,或者可能添加一个具有一定透明度的画笔?我不完全确定如何做到这一点,有人可以告诉我吗?

3 个答案:

答案 0 :(得分:2)

您可以为Style创建新的ControlTemplate来覆盖ListViewItem。这是一项很多工作,因为它需要您重新定义所有VisualStatesTriggers等。

我已经包含了足够的代码来演示代码背后的过程,这将删除圆角边框。如果你想沿着这条路走下去,我会留给你添加VisualStates

 public MainWindow()
    {
        InitializeComponent();
        messages.Add(new Message(DateTime.Now, "This is a test."));
        messages.Add(new Message(DateTime.Now, "This is a multi-line message.\nThis is a multi-line message."));
        messages.Add(new Message(DateTime.Now, "This is a multi-line message.\nThis is a multi-line message."));
        messages.Add(new Message(DateTime.Now, "This is a multi-line message.\nThis is a multi-line message."));
        messages.Add(new Message(DateTime.Now, "This is a test."));
        messages.Add(new Message(DateTime.Now, "This is a test."));
        messages.Add(new Message(DateTime.Now, "This is a test."));
        messages.Add(new Message(DateTime.Now, "This is a test."));
        ListView listView = new ListView();
        CreateListViewItemStyle(listView);
        GridView gridView = new GridView();
        listView.View = gridView;
        GridViewColumn timeStampColumn = new GridViewColumn();
        timeStampColumn.DisplayMemberBinding = new Binding("Date");
        GridViewColumnHeader timeStampHeader = new GridViewColumnHeader();
        timeStampHeader.Content = "Time";
        timeStampColumn.Header = timeStampHeader;
        gridView.Columns.Add(timeStampColumn);
        GridViewColumn messageColumn = CreateGridViewColumn("Message", "Text");
        gridView.Columns.Add(messageColumn);
        Binding binding = new Binding();
        binding.Source = messages;
        listView.SetBinding(ItemsControl.ItemsSourceProperty, binding);
        MainGrid.Children.Add(listView);
    }

    private static void CreateListViewItemStyle(ListView listView)
    {
        string xaml = @"
        <Style  xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" TargetType=""ListViewItem"">
            <Setter Property=""Height"" Value=""20""/>
            <Setter Property=""Template"">
                <Setter.Value>
                <ControlTemplate TargetType=""{x:Type ListViewItem}"">
                    <Border Background=""{TemplateBinding Background}""
                            CornerRadius=""0"">
                        <GridViewRowPresenter/>
                    </Border>
                </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <DataTrigger Binding=""{Binding Text}"" Value=""This is a test."">
                    <Setter Property=""Background"" Value=""Pink""/>
                </DataTrigger>
            </Style.Triggers>
        </Style>";
        StringReader stringReader = new StringReader(xaml);
        XmlReader xmlReader = XmlReader.Create(stringReader);
        listView.ItemContainerStyle = XamlReader.Load(xmlReader) as Style;
    }

答案 1 :(得分:1)

尝试看下面的XAML编码。使用Datagrid代替ListView。

<Window x:Class="WpfApplication1.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 DataGridRow}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver"
                     Value="True">
                <Setter Property="Background"
                        Value="Red" />
                <Setter Property="FontWeight"
                        Value="ExtraBold" />
                <Setter Property="Height"
                        Value="20" />
            </Trigger>
            <DataTrigger Binding="{Binding Text}" Value="This is a test.">
                <Setter Property="Background" Value="Pink" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid x:Name="MainGrid" />

    <DataGrid Margin="10" Grid.Row="1" x:Name="MainGrid1"
          AutoGenerateColumns="False"
          AlternationCount="2"
          FrozenColumnCount="2">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Date}"
                            Header="Time" Width="Auto" />
            <DataGridTextColumn Binding="{Binding Text}"
                            Header="Message" Width="*" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

在MainWindow的构造函数结束时,添加以下最后一行

        Binding binding = new Binding();
        binding.Source = messages;
        listView.SetBinding(ItemsControl.ItemsSourceProperty, binding);
        MainGrid.Children.Add(listView);

        MainGrid1.ItemsSource = messages;

您可能需要编写多项目以检查文本值并将鼠标悬停在其上,然后更改相应的背景颜色。

答案 2 :(得分:0)

将样式直接应用于ListView时,它似乎可以正常工作。我相信您使用GridView作为ListView视图的项目强制使用圆角样式。

如果可能的话,我建议您考虑使用不同的控件集来显示您的项目。