WPF:如何以编程方式设置 ListView 的样式,以便所有行都具有特定的背景颜色和高度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17594349/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:12:00  来源:igfitidea点击:

WPF: How do I programmatically style my ListView so that all rows have a certain background color and height?

wpflistviewgridviewstylesstyling

提问by Alexandru

I can't seem to wrap my head around something. Say I have the following logic in my code:

我似乎无法将头围绕在什么东西上。假设我的代码中有以下逻辑:

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."));
            ListView listView = new 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 = new GridViewColumn();
            messageColumn.DisplayMemberBinding = new Binding("Text");
            GridViewColumnHeader messageHeader = new GridViewColumnHeader();
            messageHeader.Content = "Message";
            messageColumn.Header = messageHeader;
            gridView.Columns.Add(messageColumn);
            Binding binding = new Binding();
            binding.Source = messages;
            listView.SetBinding(ItemsControl.ItemsSourceProperty, binding);
            MainGrid.Children.Add(listView);
        }

        public class Message
        {

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

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

How do I programmatically style my ListView so that all rows have a certain background color and height? Note, I want to avoid doing a foreach loop on the ListView's Items list and setting each ListViewItem's properties, because this list may have very many items and this could be expensive. Instead, is there not some way to do this programmatically using the Style class, or perhaps some run-time logic?

如何以编程方式设置 ListView 的样式,以便所有行都具有特定的背景颜色和高度?请注意,我想避免在 ListView 的 Items 列表上执行 foreach 循环并设置每个 ListViewItem 的属性,因为该列表可能包含非常多的项目,而这可能会很昂贵。相反,是否没有某种方法可以使用 Style 类或某些运行时逻辑以编程方式执行此操作?

回答by Alexandru

I figured it out. You can do it this way as an example:

我想到了。例如,您可以这样做:

Style style = new Style();
style.TargetType = typeof(ListViewItem);
style.Setters.Add(new Setter(ListViewItem.BackgroundProperty, Brushes.Pink));
listView.ItemContainerStyle = style;

Edit: You can also conditionally set a style on the ListView's Items using a trigger for certain values from your data set. I found this very useful, so this may help others as well:

编辑:您还可以使用触发器为数据集中的某些值有条件地在 ListView 的 Items 上设置样式。我发现这非常有用,所以这也可以帮助其他人:

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);
listView.ItemContainerStyle = style;

The above code will only set the background of the row under the condition that the Text field is set to "This is a test."

上面的代码只会在Text字段设置为“This is a test”的情况下设置行的背景。

回答by Wallstreet Programmer

GridView columns don't support styling, only header styling. Instead use a cell template to style column cells. This allows you to have different styles for different columns. For example you want currency columns to be right aligned but text columns to be left aligned.

GridView 列不支持样式,仅支持标题样式。而是使用单元格模板来设置列单元格的样式。这允许您为不同的列设置不同的样式。例如,您希望货币列右对齐但文本列左对齐。

This is how it looks using XAML for your Time column with red background style.

这是将 XAML 用于具有红色背景样式的时间列的外观。

<GridViewColumn Header="Time">                            
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Date}">
                <TextBlock.Style>
                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="Background" Value="Red" />
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

This can be done in code. FrameworkElementFactoryclass is a deprecated class which supports the creation of templates. The recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Loadmethod of the XamlReaderclass. Below code should be modified to allow for different styles depending on type of column.

这可以在代码中完成。FrameworkElementFactory类是一个不推荐使用的类,它支持创建模板。以编程方式创建模板的推荐方法是使用XamlReader类的Load方法从字符串或内存流加载 XAML 。应修改下面的代码以允许根据列的类型使用不同的样式。

public MainWindow()
{
    InitializeComponent();

    messages.Add(new Message(DateTime.Now, "This is a test."));

    ListView listView = new ListView();
    GridView gridView = new GridView();
    listView.View = gridView;

    gridView.Columns.Add(CreateGridViewColumn("Time", "Date"));
    gridView.Columns.Add(CreateGridViewColumn("Message","Text"));

    listView.SetBinding(ItemsControl.ItemsSourceProperty, new Binding() { Source = messages });

    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""> 
            <TextBlock Text=""{Binding " + bindingPath + @"}""> 
                <TextBlock.Style>
                    <Style TargetType=""{x:Type TextBlock}"">
                        <Setter Property=""Background"" Value=""Red"" />
                    </Style>
                </TextBlock.Style>
            </TextBlock>
            </DataTemplate>";
    StringReader stringReader = new StringReader(xaml);
    XmlReader xmlReader = XmlReader.Create(stringReader);
    gridViewColumn.CellTemplate = XamlReader.Load(xmlReader) as DataTemplate;

    return gridViewColumn;
}