Shakir Ahmed
Shakir Ahmed

Reputation: 547

How to manipulate specific ListViewItem from ListView

I want to mark a ListViewItem from a ListView by changing the foreground color of the textblock which is in the listviewitem. I want to do that dynamically. Whenever a user selects the item, the TextBlock's foreground color should be changed. Here is the Templete

<ListView Name="SongsListView"
                              IsItemClickEnabled="True"
                              ItemClick="SongsListView_ItemClick"
                          ItemsSource="{x:Bind rootpage.Songs}"
                      VerticalAlignment="Top" 
                      HorizontalAlignment="Stretch">
                        <ListView.ItemTemplate>
                            <DataTemplate x:DataType="model:Song">
                                <controls:DropShadowPanel ShadowOpacity="0.20"
                                          Color="Black"
                                          HorizontalContentAlignment="Stretch"
                                          BlurRadius="10"
                                          OffsetX="0"
                                          OffsetY="7.0">
                                    <Grid HorizontalAlignment="Stretch" CornerRadius="5" Background="{ThemeResource SystemControlAltHighAcrylicElementBrush}">
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{x:Bind Name}" Name="songNameTextBlock" TextWrapping="Wrap"/>
                                            <TextBlock Text="{x:Bind Artist}" Name="ArtistNameTextBlock" TextWrapping="Wrap"/>
                                        </StackPanel>
                                    </Grid>
                                </controls:DropShadowPanel>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                        <ListView.ItemContainerStyle>
                            <Style TargetType="ListViewItem">
                                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                                <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                                <Setter Property="Margin" Value="4"/>
                            </Style>
                        </ListView.ItemContainerStyle>
                    </ListView>

 private void SongsListView_ItemClick(object sender, ItemClickEventArgs e)
    {
        //Please write the code for me !
    }

Upvotes: 0

Views: 74

Answers (1)

Xie Steven
Xie Steven

Reputation: 8591

I would suggest you to define a foreground relevant property in your Song class and bind it to the TextBlock's Foreground property. Then you could use Binding/{x:Bind} to change its foreground color when it's selected, instead of using the ItemClick event handler method to find the TextBlock controls in it.

Please refer to the following code sample for details:

<ListView Name="SongsListView"
                  IsItemClickEnabled="True"
                  ItemsSource="{x:Bind Songs}"
                  VerticalAlignment="Top" 
                  HorizontalAlignment="Stretch" SelectedItem="{x:Bind currentSelectedItem,Mode=TwoWay,Converter={StaticResource myconverter}}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="model:Song">
                <controls:DropShadowPanel ShadowOpacity="0.20"
                                      Color="Black"
                                      HorizontalContentAlignment="Stretch"
                                      BlurRadius="10"
                                      OffsetX="0"
                                      OffsetY="7.0">
                    <Grid HorizontalAlignment="Stretch" CornerRadius="5" Background="{ThemeResource SystemControlAltHighAcrylicElementBrush}">
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{x:Bind Name}" Name="songNameTextBlock" TextWrapping="Wrap" Foreground="{x:Bind customcolor,Mode=OneWay}"/>
                            <TextBlock Text="{x:Bind Artist}" Name="ArtistNameTextBlock" TextWrapping="Wrap" Foreground="{x:Bind customcolor,Mode=OneWay}"/>
                        </StackPanel>
                    </Grid>
                </controls:DropShadowPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                <Setter Property="Margin" Value="4"/>
            </Style>
        </ListView.ItemContainerStyle>
</ListView>
<Page.Resources>
    <local:MyConverter x:Key="myconverter"></local:MyConverter>
</Page.Resources>
public sealed partial class MainPage : Page
{

    public ObservableCollection<Song> Songs { get; set; }

    private Song _currentSelectedItem;
    public Song currentSelectedItem
    {
        get { return _currentSelectedItem; }
        set
        {
            if (_currentSelectedItem != null)
            {
                _currentSelectedItem.customcolor = new SolidColorBrush(Colors.Black);
            }
            _currentSelectedItem = value;
            _currentSelectedItem.customcolor = new SolidColorBrush(Colors.Red);
        }
    }


    public MainPage()
    {
        this.InitializeComponent();
        Songs = new ObservableCollection<Song>();
        Songs.Add(new Song() {Name="abc",Artist="Singer1" });
        Songs.Add(new Song {Name="def",Artist="Singer2" });

    }
}
public class Song : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string PropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }

    private string _Name;
    public string Name
    {
        get { return _Name; }
        set
        {
            _Name = value;
            RaisePropertyChanged("Name");
        }
    }

    private string _Artist;
    public string Artist
    {
        get { return _Artist; }
        set
        {
            _Artist = value;
            RaisePropertyChanged("Artist");
        }
    }

    private SolidColorBrush _customcolor = new SolidColorBrush(Colors.Black);
    public SolidColorBrush customcolor
    {
        get { return _customcolor; }
        set
        {
            _customcolor = value;
            RaisePropertyChanged("customcolor");
        }
    }
}
public class MyConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value as Song;
    }
}

enter image description here

Please note that I make a converter class and use it when I bind currentSelectedItem to ListView's SelectedItem. Because I used x:Bind, it's compile time. If you do not add a converter, you will get error Invalid binding path 'currentSelectedItem' : Cannot bind type 'AppListView.model.Song' to 'System.Object' without a converter.

Besides, you could see I set Mode=OneWay when I use {x:Bind} to bind customcolor to TextBlock's foreground. It's due to the default value of {x:Bind}'s mode is OneTime. If you do not change OneTime to OneWay, you will not see the foreground color changed.

Upvotes: 1

Related Questions