1

假设我有以下代码(您可以创建一个新的 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 有轻微的圆角。我怎样才能消除这种影响?

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

4

3 回答 3

2

您可以Style通过ControlTemplateListViewItem. 这是很多工作,因为它需要你重新定义所有的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;
    }
于 2013-07-11T20:04:37.643 回答
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;

您可能需要编写多重触发器来检查文本值和鼠标悬停,然后更改适当的背景颜色。

于 2013-07-11T18:43:41.783 回答
0

将您的样式直接应用于 ListView 时,它似乎可以按您的意愿工作。我相信圆形样式被您用作 ListView 的视图的 GridView 强制施加在项目上。

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

于 2013-07-11T18:45:57.637 回答