je30ca
je30ca

Reputation: 96

Change DataTemplate for ListBox item if selected in UWP

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>

Upvotes: 0

Views: 1918

Answers (1)

Grace Feng
Grace Feng

Reputation: 16652

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?.

Upvotes: 3

Related Questions