4

I have a ListBox where I defined a DataTemplate for its items:

<ListBox.ItemTemplate>
    <DataTemplate>
        <Border>
            <TextBlock Text="{Binding Name}" />
        </Border>
    </DataTemplate>
</ListBox.ItemTemplate>

And the class I use to add elements into the ListBox is the following:

public class MyItem
{
    public string Name
    { get; set; }
}

Now I need to change the background of the ListBox item, when for example the item has been selected:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count == 1)
    {
        var item = e.AddedItems.First() as MyItem;
    }
}

the problem is that the item is of type MyItem, while I need access to the Border and TextBlock objects as well.

gliderkite
  • 8,828
  • 6
  • 44
  • 80
  • is your app UWP or WPF? – SWilko Jun 03 '16 at 08:33
  • @Pikoh I'm asking for UWP. – gliderkite Jun 03 '16 at 08:34
  • ups just realized it. Sorry – Pikoh Jun 03 '16 at 08:34
  • does this [answer](http://stackoverflow.com/questions/37568516/display-default-background-color-of-listview-item-in-windows-10-uwp/37569540#37569540) help – SWilko Jun 03 '16 at 08:35
  • 1
    To get a `TextBlock` inside an template and change it's properties in code you should use `FrameworkTemplate.FindName` Method. Check this answer: http://stackoverflow.com/questions/34117944/listbox-items-return-string-when-datatemplate-is-button – Salah Akbari Jun 03 '16 at 08:35
  • Have a look at [this](https://social.msdn.microsoft.com/Forums/sqlserver/en-US/7f91dfdb-41cc-42ca-9635-7666c1b99813/uwpxaml-change-background-color-of-listbox-selected-item?forum=wpdevelop) – Pikoh Jun 03 '16 at 08:35

2 Answers2

1

You can use a fancy RelativeSource binding on your Border style:

<Border.Style>
    <Style TargetType="Border">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}}" Value="True">
                <Setter Property="Background" Value="Pink"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Border.Style>

This will create a DataTrigger that will bind to the IsSelected property of the parent ListBoxItem, when it is selected then it will set the background colour of the Border to Pink.

Mike Eason
  • 9,525
  • 2
  • 38
  • 63
0

the problem is that the item is of type MyItem, while I need access to the Border and TextBlock objects as well.

If you just want to change the background when item is selected, you can refer to the answers in the comments and @Mike Eason's answer.

But I think your main purpose here is to get the Border control in your selected item using SelectionChanged event of ListBox. As @S.Akbari offered, you can use VisualTreeHelper to find the border, but there is other easier method here you can use for example.

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var listBox = sender as ListBox;
    var container = listBox.ContainerFromItem(listBox.SelectedItem) as ListBoxItem;
    var border = container.ContentTemplateRoot as Border;
    border.Background = new SolidColorBrush(Colors.Pink);
}

Using ItemsControl.ContainerFromItem method can help you to find the container corresponding to the specified item, and then since your Border is the root control in your DataTemplate, we can use ContentControl.ContentTemplateRoot property to get the root element of the data template specified by ContentTemplate property.

Grace Feng
  • 16,564
  • 2
  • 22
  • 45