0

In UWP Xaml,I have a ListView. In the ListView i use a DataTemplate with a stack panel, I want change backgrund color of stackpanel when selectedItem is True I do want to do it in Xaml

the other words,

Change DataTemplate for Listview item if selected I do want to do it in Xaml

code in Xaml:

<ListView.ItemTemplate >
    <DataTemplate x:Name="mydt">

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="40" />
            </Grid.ColumnDefinitions>
            <StackPanel x:Name="MyStack">
                <ContentControl Content="{Binding rtb}"
                                q:APGolAyah.MyProperty="{Binding AyahNo}" />                           
                <TextBlock Text="{Binding Text}"
                           TextWrapping="Wrap" />

            </StackPanel>
            <Image Grid.Column="1"
                   Source="{Binding HezbNo,Converter={StaticResource HezbNoToIconConverter}}"
                   Width="25" />
        </Grid>
    </DataTemplate>
</ListView.ItemTemplate>
je30ca
  • 96
  • 10
  • A lot of [resources on the net](https://www.google.co.uk/search?q=xaml+listview+selected+item+style&oq=xaml+selecteditem+sty&aqs=chrome.1.69i57j0l5.11897j0j7&sourceid=chrome&ie=UTF-8) on how to accomplish that. – Michael Oct 18 '16 at 09:56
  • @Michael yes but it seems that uwp xaml doesn't support triggers in styles – je30ca Oct 18 '16 at 09:59
  • 1
    Apologies, didn't look into it thoroughly that this applies to UWP. That being said, I believe there are others who faced [the same limitation](http://stackoverflow.com/a/31933556/997668). – Michael Oct 18 '16 at 10:04
  • You can do this by restyling the list and changing the selection color. Or you can do it at the datatemplate level using a converter. – disklosr Oct 18 '16 at 16:49

1 Answers1

3

As you've found that in UWP Style.Triggers cannot be used, and I understand that you want to do this work pure in xaml, but sorry to say that there is no such pure way now.

Since you only want to change the background color of the StackPanel when the item is selected, I think it is not needed to changed the whole DataTemplate, I'm writing the answer here to introduce a method which uses Converter for data binding and a little bit c# code here since maybe you interest in this method.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <local:BoolToBrushConverter x:Key="cvt" />
    </Grid.Resources>
    <ListView x:Name="listview" ItemsSource="{x:Bind Collection, Mode=OneWay}"
              SelectionChanged="listview_SelectionChanged">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="40" />
                    </Grid.ColumnDefinitions>
                    <StackPanel Background="{Binding IsSelected, Converter={StaticResource cvt}}">
                        <TextBlock Text="{Binding Name}" />
                    </StackPanel>
                    <TextBlock Grid.Column="1" Text="{Binding Age}" />
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

Code behind and data model:

private ObservableCollection<Model> Collection = new ObservableCollection<Model>();

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    for (int i = 0; i < 50; i++)
    {
        Collection.Add(new Model { Name = "Name " + i + ", ", Age = i });
    }
}

private void listview_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    foreach (Model item in e.AddedItems)
    {
        item.IsSelected = true;
    }
    foreach (Model item in e.RemovedItems)
    {
        item.IsSelected = false;
    }
}

public class Model : INotifyPropertyChanged
{
    public string Name { get; set; }
    public int Age { get; set; }

    private bool _IsSelected;

    public bool IsSelected
    {
        get { return _IsSelected; }
        set
        {
            if (value != _IsSelected)
            {
                _IsSelected = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName]string propertyName = "")
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Converter:

public class BoolToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        bool? b = (bool?)value;
        if (b == true)
            return new SolidColorBrush(Colors.BlueViolet);
        return new SolidColorBrush(Colors.Transparent);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

And if you also interest in changing DataTemplate, you may refer to my answer in another case: UWP ListView: How to expand an item when select it?.

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