【问题标题】:WPF: How do I programmatically style my ListView so that all rows have a certain background color and height?WPF:如何以编程方式设置我的 ListView 的样式,以便所有行都具有特定的背景颜色和高度?
【发布时间】:2013-07-11 13:12:54
【问题描述】:

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

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; }
        }
    }
}

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

【问题讨论】:

  • 为什么要在代码隐藏中而不是通过 xaml Template's 来做这些事情?这里使用代码隐藏的强制因素是什么?
  • @Viv - 那么,对于上述示例,这在 XAML 中的外观如何?我在 XAML 中没有 ListView,它是动态生成的,所以如果可能的话,我需要 XAML 样式来为动态生成的 ListView 工作。
  • 首先为什么你在 xaml 中没有ListViewListView 的内容可以通过 ItemsSource 绑定使其动态化,但是您是否处于不知道窗口中是否需要 ListView 的用例?即使在这种情况下,我也会让 xaml 相应地显示或隐藏控件。我想不出这个“必须”来自代码隐藏的原因。至于您的问题,即使您必须在代码隐藏中生成 ListView,是的,您可以使用 TryFindResource(...) 之类的东西获得 Style 或 xaml 中定义的任何资源,但是请考虑不要这样做。
  • @Viv - 我让这个示例代码成为一个更大项目的最简单案例,以便人们更好地理解问题并帮助我找到解决方案。我在我的项目中使用 Telerik 的 RadPanes,所以我必须动态地将这些控件添加到每个窗格中,并且我不能简单地标记所有内容。现在,有没有办法以编程方式为其 Items 集合定义 ListView 的样式?您能否在这里发布一个如何使用 TryFindResource 的示例?
  • 伙计,如果你要在 WPF 中编程,你最好习惯 XAML。然后造型变得容易,有很多教程。 This one 例如。您可以创建 UserControl,其中包含您在代码中添加的所有这些控件以及一些样式。

标签: wpf listview gridview styles styling


【解决方案1】:

我想通了。你可以这样做作为一个例子:

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

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

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;

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

【讨论】:

    【解决方案2】:

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

    这是使用 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>
    

    这可以在代码中完成。 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;
    }
    

    【讨论】:

    • +1 因为它很有趣,虽然我只是想设置行的样式,而不是列。不过我想通了,看看我的答案:P 谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2021-10-18
    • 1970-01-01
    • 2014-06-24
    • 2011-03-30
    • 1970-01-01
    • 2017-06-20
    相关资源
    最近更新 更多