How to add style for every listbox.Item in code behind?

366 Views Asked by At

i am trying to add different styles for every listbox.Item in my project. Can anyone help me about that?

`



            foreach (var item in orderList)
            {
                var itm = new ListBoxItem();

                if (item.CustomOrder)
                {
                    itm.Content = item;
                    itm.Style = customOrderStyle;
                    listbox.Items.Add(itm);


                }
                else
                {
                    itm.Content = item;
                    itm.Style = newOrderStyle;
                    listbox.Items.Add(itm);


                }
            }

`

My content doesnt shown like this.

I know that i am adding Listbox item to the listbox, that's why content is doesnt shown. I try some different things too but still dont know how to solve it.

2

There are 2 best solutions below

0
EldHasp On BEST ANSWER

An example of a more typical for WPF implementation:

namespace Core2022.SO.Ali.ListBoxItemStyleSelector
{
    public class OrderItem
    {
        public bool CustomOrder { get; set; }

        public int Id { get; set; }
    }
}
using System.Collections.ObjectModel;

namespace Core2022.SO.Ali.ListBoxItemStyleSelector
{
    public class OrderViewModel
    {
        public ObservableCollection<OrderItem> Orders { get; } = new ObservableCollection<OrderItem>();

        public OrderViewModel()
        {
            for (int i = 0; i < 10; i++)
            {
                Orders.Add(new OrderItem() { Id = i, CustomOrder = i % 2 == 0 });
            }
        }
    }
}
using System;
using System.Windows;
using System.Windows.Controls;

namespace Core2022.SO.Ali.ListBoxItemStyleSelector
{
    public class CustomOrderStyleSelector : StyleSelector
    {
        public Style? CustomOrderTrue { get; set; }
        public Style? CustomOrderFalse { get; set; }

        public override Style SelectStyle(object item, DependencyObject container)
        {
            if (item is OrderItem order)
            {
                return (order.CustomOrder ? CustomOrderTrue : CustomOrderFalse)
                    ?? throw new NullReferenceException(); ;
            }
            return base.SelectStyle(item, container);
        }
    }
}
<Window x:Class="Core2022.SO.Ali.ListBoxItemStyleSelector.OrdersWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Core2022.SO.Ali.ListBoxItemStyleSelector"
        mc:Ignorable="d"
        Title="OrdersWindow" Height="300" Width="200"
        DataContext="{DynamicResource vm}">
    <FrameworkElement.Resources>
        <local:OrderViewModel x:Key="vm"/>
        <local:CustomOrderStyleSelector x:Key="customOrderStyleSelector">
            <local:CustomOrderStyleSelector.CustomOrderTrue>
                <Style TargetType="ListBoxItem">
                    <Setter Property="Foreground" Value="Green"/>
                    <Setter Property="FontSize" Value="15"/>
                </Style>
            </local:CustomOrderStyleSelector.CustomOrderTrue>
            <local:CustomOrderStyleSelector.CustomOrderFalse>
                <Style TargetType="ListBoxItem">
                    <Setter Property="Background" Value="Coral"/>
                    <Setter Property="HorizontalContentAlignment" Value="Center"/>
                </Style>
            </local:CustomOrderStyleSelector.CustomOrderFalse>
        </local:CustomOrderStyleSelector>
    </FrameworkElement.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Orders}"
                 DisplayMemberPath="Id"
                 ItemContainerStyleSelector="{DynamicResource customOrderStyleSelector}"/>
    </Grid>
</Window>

enter image description here

3
BionicCode On

Check the Data Templating Overview link and go to the "Creating the DataTemplate as a Resource" section (and read the next section too). It shows how to define a DataTemplate as a resource and how to use the DataTemplate.DataType property. Just don't give the template a x:Key so that WPF can pick the proper template based on the item type automatically.

Then define a data model for each individual looking item and stop what you are doing: don't create ListBoxItem explicitly (let WPF do it via the DataTemplate). And instead of checking for the CustomOrder property, introduce related model classes e.g. DefaultOrder and CustomOrder. Then add items of those types to a common source collection that you bind to your ListBox:

IOrder.cs

interface IOrder
{
  ...
}

DefaultOrder.cs

class DefaultOrder : IOrder
{
  ...
}

CustomOrder.cs

class CustomOrder : IOrder
{
  ...
}

MainWindow.xaml

<Window>
  <ListBox x:Name="OrdersOverview">
    <ListBox.Resources>
      <DataTemplate DataType="{x:Type local:DefaultOrder}">
        ...
      </DataTemplate>

      <DataTemplate DataType="{x:Type local:CustomOrder}">
        ...
      </DataTemplate>
    </ListBox.Resources>
  </ListBox>
</Window>

MainWindow.xaml.cs

prtial class MainWindow : Window
{
  private ObservableCollection<IOrder> Orders { get; }

  public MainWindow()
  {
    InitializeComponent();

    this.Orders = new ObservableCollection<IOrder>();
    this.OrdersOverview.ItemsSource = this.Orders;
  }

  private void CreateDefaultOrder()
  {
    var newOrder = new DefaultOrder();

    // Show the new order in the ListBox
    this.Orders.Add(newOrder);
  }


  private void CreateCustomOrder()
  {
    var newOrder = new CustomOrder();

    // Show the new order in the ListBox
    this.Orders.Add(newOrder);
  }
}