UWP: changing the (text) style of a ListBoxItem El

2019-09-19 20:13发布

问题:

I have a listbox with many listboxitems inside. those items only contain text elements. What I want to do is change the text style (and maybe the background colour as well) for a single listboxitem in c# code (as I need to apply conditions). how would I go about that?

XAML:

<ListBox x:Name="todoList" Margin="5, 5, 5, 5" Grid.Row="1" SelectionChanged="todoList_SelectionChanged"/>

I fill the listbox by parsing a file and then adding items to the listbox.

Subclassing the ItemControlStyleSelector did not seem to work in my case as you cannot overwrite the SelectStyle function in the UWP case.

I am able to apply a style to the WHOLE ListBox (all ListBoxItems) by:

Style st = new Style();
st.TargetType = typeof(ListBoxItem);
st.Setters.Add(new Setter(ListBoxItem.BackgroundProperty, "Blue"));
todoList.ItemContainerStyle = st;

What would a good approach be to change only one item's style in code? The goal is to apply some styling to certain items after the user pressed a specific button / key on the keyboard.

thanks!

回答1:

The ListBox does not provide the build-in support to change the style of a specific ListBoxItem.

The workaround is using VisualTreeHelper:

XAML:

    <ListBox x:Name="todoList">
        <ListBoxItem>Item#1</ListBoxItem>
        <ListBoxItem>Item#2</ListBoxItem>
        <ListBoxItem>Item#3</ListBoxItem>
        <ListBoxItem>Item#4</ListBoxItem>
        <ListBoxItem>Item#5</ListBoxItem>
    </ListBox>

C#:

public void OnClick(Object sender, RoutedEventArgs e)
{
    var results = new List<ListBoxItem>();

    FindChildren(results, todoList);

    results[2].Background = new SolidColorBrush(Color.FromArgb(120, 0, 0, 255));
}

internal static void FindChildren<T>(List<T> results, DependencyObject startNode) where T : DependencyObject
{
    int count = VisualTreeHelper.GetChildrenCount(startNode);

    for (int i = 0; i < count; i++)
    {
        DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
        if ((current.GetType()).Equals(typeof(T)) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
        {
            T asType = (T)current;
            results.Add(asType);
        }

        FindChildren<T>(results, current);
    }
}