简体   繁体   中英

WPF listbox with different colors

i have a problem with an listbox that should countain different colors in his Items.

    <ListBox i:Name="listBox1" ItemsSource="{Binding MyItems_listbox1}" 
     IsSynchronizedWithCurrentItem="True">

Now i want to add an item to the list box were the string is written in different colors for example:

listBox1.Items.Add("hallo my name");

I want that "hallo"(blue) "my"(red) "name"(green) will be added to the listbox and displayed. Is there some possible way to realize this ???

The Probable way to acheive this might be using the ListBox DataTemplate where you will send the string as an array and then inside the DataTemplate you can have different TextBlock for all the parts of string

<TextBlock Text="hallo " Foreground="Blue" />
<TextBlock Text="my" Foreground="Red" />
<TextBlock Text=" name" Foreground="Green" />

To highlight some word, normally we can thought of RichTextBox control. However it's not a light weight control. It's fortunate that WPF supports many controls (especially related to Document ) allowing us to display rich text. For a lightweight solution, you should just use a TextBlock representing the content for each ListViewItem but we can use the Run elements inside each TextBlock to highlight the words. Firstly we need to use DataTemplate to set ItemTemplate for each ListViewItem . We have to use Binding to bind the string content (of each item) to a TextBlock inside the DataTemplate . Using Binding allows us to inject some custom code in the Converter . Here is the details code:

Code behind :

//The main window class
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        //Init the Keywords first
        Keywords.Add("hallo", Brushes.Blue);
        Keywords.Add("my", Brushes.Red);
        Keywords.Add("name", Brushes.Green);

        //Add some items to the ListView
        lv.Items.Add("hallo my name");
        lv.Items.Add("hello my name");
        lv.Items.Add("goodbye your name");            
    }
    //This dictionary used to hold your keywords corresponding to their Brush
    public static Dictionary<string, Brush> Keywords = new Dictionary<string,Brush>();
}

//The converter class
public class InlinesConverter : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var content = Convert.ToString(value);
        var dict = MainWindow.Keywords;
        var outString = "<TextBlock xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"  xml:space=\"preserve\">";
        foreach(var word in content.Split(' ')){
            var converted = word;
            Brush fg;
            if (dict.TryGetValue(word, out fg)) {
                var run = new Run(word);
                run.Foreground = fg;
                converted = System.Windows.Markup.XamlWriter.Save(run);
            }
            outString += converted + " ";
        }
        outString += "</TextBlock>";            
        return System.Windows.Markup.XamlReader.Parse(outString);            
    }

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML :

<Window x:Class="WpfApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="SO3" Height="300" Width="300"
    xmlns:local="clr-namespace:WpfApplication"
    >
  <Window.Resources>
    <local:InlinesConverter x:Key="inlinesConverter"/>
  </Window.Resources>
  <Grid>
    <ListView Name="lv">            
        <ListView.ItemTemplate>
            <DataTemplate>                    
                <ContentControl FontSize="20">
                   <Binding Converter="{StaticResource inlinesConverter}"/>
                </ContentControl>
            </DataTemplate>
        </ListView.ItemTemplate>            
    </ListView>
  </Grid>
</Window>

Note about the namespace here, in this demo I used the default namespace WpfApplication . If yours is different, you should edit it inside the XAML code. Also note that the ItemTemplate is ignored if you add the items right in the XAML code. We have to use the code behind either via Items.Add or data binding (with ItemsSource ).

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM