【问题标题】:How to change color of the selected ListView item [WP8.1]如何更改所选 ListView 项的颜色 [WP8.1]
【发布时间】:2014-10-25 03:00:38
【问题描述】:

我正在为 Windows Phone 8.1 开发一个 C# 项目,我不敢相信我已经浪费了将近一天的时间来寻找解决这样一个微不足道的问题的方法:

我有一个使用 XAML 定义的页面,在该页面上我有一个 ListView。在某些时候,我希望其中一个列表视图项被选中,所以我调用 myListView.SelectedIndex = 不管。现在我希望该项目在视觉上与其他项目区分开来,例如,用不同的颜色绘制其文本。我怎么做?以下是代码的相关部分:

<Page.Resources>
    <DataTemplate x:Key="myListItemTemplate">
        <TextBlock 
            Text="{Binding displayName}" 
            Style="{ThemeResource ListViewItemTextBlockStyle}"
            />
   </DataTemplate>
</Page.Resources>

<ListView 
    x:Name="myListView" 
    ItemsSource="{Binding}" 
    ItemTemplate="{StaticResource myListItemTemplate}" 
    >
</ListView>

单独使用 XAML 是否可行?或者可以在 C# 代码中完成,就在我设置 myListView.SelectedIndex 值时?

谢谢!

【问题讨论】:

  • 嗨,Andrei,你可以很容易地将我的 LongListSelector 代码改写为 ListView。我想我解释得很好。看看:stackoverflow.com/questions/25070203/…
  • 我试过这样的方法,它有效,但是当项目列表很大时它太慢了。我希望可以在 XAML 本身中指定选定的项目样式,而不是在数据中设置颜色,循环遍历整个集合。
  • 是的,该解决方案没有任何优化,因此人们可以更好地理解它。如果您想避免循环,您需要将 SelectedIndex 数据绑定到您的 ViewModel,并在更改时引发事件。如果你想要一个完整的 XAML 解决方案,我回家后可能会给你写一个示例。
  • 再次检查解决方案以获得纯 XAML 解决方案。

标签: c# xaml listview windows-phone-8.1


【解决方案1】:

您需要为您的 ListBoxItem 创建一个样式并使用情节提要。

这是一个示例:

  <Page.Resources>
<Style x:Key="ListViewItemTemplate" TargetType="ListViewItem">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ListViewItem">
        <Border x:Name="LayoutRoot">
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="SelectionStates">
              <VisualState x:Name="Unselected">
                <Storyboard>
                  <!-- Define style -->
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="container" Storyboard.TargetProperty="Background">
                    <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Selected">
                <Storyboard>
                  <!-- Define style -->
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="container" Storyboard.TargetProperty="Background">
                    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <Grid Margin="0,5" x:Name="container" Background="Transparent">
            <!-- Definition of your list item. -->
          </Grid>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

以及列表视图的定义:

<ListView ItemContainerStyle="{StaticResource ListViewItemTemplate}" SelectionMode="Single" />

【讨论】:

  • 我将您提供的代码添加到我的 XAML 中,但它并没有改变所选项目的外观。还有其他建议吗?谢谢。
  • SelectionMode 已经是单一的,默认的。在我将 ItemContainerStyle 添加到 ListView 后,发生了一些变化,您的代码似乎开始生效,但它破坏了数据绑定:不再从模型数据源填充列表。
  • 现在正式发布了:一整天都浪费在试图改变所选项目的颜色...
  • 您是否在没有重新添加 itemsource 的情况下复制和粘贴?
  • ItemSource 仍然存在。谁能给我指出一个适用于 Windows Phone 8.1 的示例代码? WP7 代码不适用于 WP8.1。
【解决方案2】:

是的,您需要在所选属性上设置带有触发器的样式。在我的手机上很难输入代码,但快速谷歌会向您展示大量示例或在这里:ListBox Style Selected item on windows phone

【讨论】:

  • 这个例子使用数据绑定来改变选中项的状态,这对于一些项来说很好,但是对于大列表来说效率非常低:每次我需要改变选择时,我都需要枚举整个列表。我希望有一个不需要这样做的解决方案。
  • 我不知道你读了什么,但我链接的问题的答案使用了一个应用于列表项的模板。我还声明使用属性触发器来应用样式。两者都不使用循环策略。
  • 我认为你回复了错误的评论,哈哈。 chubosaurus 评论使用循环策略
  • 如果您查看您链接的示例,您会看到它使用数据绑定到属性 IsSelected,这就是我所指的,对于大型数据集,这不是一个好的解决方案。至于触发器,我找不到适用于 Windows Phone 8.1 的示例代码您链接到的文章适用于 WP7,不适用于 WP8.1。
【解决方案3】:

K,Andrei 我认为提供的解决方案非常好,只是有问题。这是我的。

XAML : 注意 SelectedUnfocused


    <ListView x:Name="mylistview">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">                    
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">                                
                            <Grid>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal"/>
                                    </VisualStateGroup>
                                    <VisualStateGroup x:Name="SelectionStates">
                                        <VisualState x:Name="Unselected">
                                            <Storyboard>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="myback" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="Transparent"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="SelectedUnfocused">                                                
                                            <Storyboard>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="myback" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="Red"/>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Border x:Name="myback" Background="Transparent">
                                    <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
                                </Border>
                            </Grid>                                
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Height="100">
                <TextBlock Text="{Binding Artist}" FontSize="22"/>
                <TextBlock Text="{Binding Song}" FontSize="22"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>        

C#(示例模型)

public class sample_data
{
    public sample_data(string artist, string song)
    {
        this.Artist = artist;
        this.Song = song;
    }

    public string Artist { get; set; }
    public string Song { get; set; }
}

private ObservableCollection<sample_data> CreateData()
{
    //List<sample_data> my_list = new List<sample_data>();
    ObservableCollection<sample_data> my_list = new ObservableCollection<sample_data>();

    my_list.Add(new sample_data("Faith + 1", "Body of Christ"));
    my_list.Add(new sample_data("Faith + 1", "Christ Again"));
    my_list.Add(new sample_data("Faith + 1", "A Night With the Lord"));
    my_list.Add(new sample_data("Faith + 1", "Touch Me Jesus"));
    my_list.Add(new sample_data("Faith + 1", "I Found Jesus (With Someone Else)"));
    my_list.Add(new sample_data("Faith + 1", "Savior Self"));
    my_list.Add(new sample_data("Faith + 1", "Christ What a Day"));
    my_list.Add(new sample_data("Faith + 1", "Three Times My Savior"));
    my_list.Add(new sample_data("Faith + 1", "Jesus Touched Me"));
    my_list.Add(new sample_data("Faith + 1", "Lord is my Savior"));
    my_list.Add(new sample_data("Faith + 1", "I Wasn't Born Again Yesterday"));
    my_list.Add(new sample_data("Faith + 1", "Pleasing Jesus"));
    my_list.Add(new sample_data("Faith + 1", "Jesus (Looks Kinda Hot)"));
    my_list.Add(new sample_data("Butters", "What What"));
    return my_list;
}

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    ObservableCollection<sample_data> sd = this.CreateData();
    mylistview.ItemsSource = sd;
}

运行截图:

【讨论】:

  • 一个极好的答案。它对我来说非常有效。谢谢。
  • 很抱歉碰到这个问题,但是如果我想在我的类中使用绑定到一个属性并使用它来定义自定义样式怎么办?我想在ControlTemplate 中使用{Binding Property}
  • 嗨,我正在为通用 Windows 平台编写 ListView,但这对我不起作用。 Windows 10 有什么变化吗?
【解决方案4】:

您可以向您的类添加一个布尔变量 IsSelected,并将其转换为背景颜色。例如:

   <DataTemplate>
        <Grid Background="{Binding IsSelected, Converter={StaticResource IsSelectedToBackgroundColorConverter}}">
            <TextBlock Text="{Binding displayName}" 
                       Style="{ThemeResource ListViewItemTextBlockStyle}" />
        </Grid>
   </DataTemplate>

|

class IsSelectedToBackgroundColorConverter: IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, string language)
    {

        bool IsSelected = (bool)value;

        if (IsSelected)
        {
            Windows.UI.Xaml.Media.Brush red = new SolidColorBrush(Windows.UI.Colors.Red);

            return red;
        }
        else
        {
            Windows.UI.Xaml.Media.Brush transparent = new SolidColorBrush(Windows.UI.Colors.Transparent);

            return transparent;
        }

    }

}

【讨论】:

  • 是的,这行得通,但是当数据集很大时它会很慢。此外,它不太符合 MVVM 理念:“selected”属性属于视图,而不属于数据。 Chubosaurus Software提供的解决方案在这方面要好很多。还是谢谢!
【解决方案5】:

您只需将以下内容添加到 App.xaml

</Application.Resources> <SolidColorBrush x:Key="ListViewItemSelectedBackgroundThemeBrush" Color="#92D050" /> <Application.Resources>

“十六进制颜色”将是应用程序范围内 ListView 中的选定项颜色

【讨论】:

    【解决方案6】:

    试试这个,希望对你有帮助。

    if (e.AddedItems != null) {
        foreach (var item in e.AddedItems) {
            ListViewItem litem = (sender as ListView).ContainerFromItem(item) as ListViewItem;
            if (litem != null) {
                VisualStateManager.GoToState(litem, "Unfocused", true);
                VisualStateManager.GoToState(litem, "Normal", true);
                VisualStateManager.GoToState(litem, "Selected", true);
            }
        }
    }
    if (e.RemovedItems != null) {
        foreach (var item in e.RemovedItems) {
            ListViewItem litem = (sender as ListView).ContainerFromItem(item) as ListViewItem;
            if (litem != null) {
                VisualStateManager.GoToState(litem, "Unselected", true);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-03-07
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多