【问题标题】:UWP ListView Update Row Background After Drag and Drop拖放后UWP ListView更新行背景
【发布时间】:2019-09-09 14:04:57
【问题描述】:

我目前这样做是为了让我的 ListView 具有交替的行背景。

    private void SongsListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
    {
        if (AlternatingRowColor)
            args.ItemContainer.Background = args.ItemIndex % 2 == 0 ? Helper.WhiteSmokeBrush : Helper.WhiteBrush;
    }

此外,我还允许我的ListView 能够拖放项目。但是,即使我这样做,行颜色也不会在删除后更新其颜色:

    private void SongsListView_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
    {
        sender.UpdateLayout(); // Refresh Row Color
    }

意味着我的ListView 在拖放后没有交替背景。

我应该如何更新它的背景?

【问题讨论】:

    标签: c# listview uwp win-universal-app


    【解决方案1】:

    ContainerContentChanging是初始化渲染,UpdateLayout用来保证元素已经渲染,而不是重新渲染整个列表。

    根据您的情况,我建议使用IValueConverter 进行背景颜色转换。您可以将Index 属性添加到数据类型以识别它现在的位置。

    这是一个简单的例子:

    TestModel.cs

    public class TestIndex:INotifyPropertyChanged
    {
        private int _index;
        public int Index
        {
            get => _index;
            set
            {
                _index = value;
                OnPropertyChanged();
            }
        }
    
        // other properties
    
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName]string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    converter.cs

    public class BackgroundConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if(value is int index)
            {
                // You can change color here.
                if (index % 2 == 0)
                    return new SolidColorBrush(Colors.Red);
                else
                    return new SolidColorBrush(Colors.Blue);
            }
            return new SolidColorBrush(Colors.Red);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
    

    xaml

    <Page ...>
        <Page.Resources>
            <local:BackgroundConverter x:Key="BackgroundConverter"/>
            <DataTemplate x:Key="DefaultRow" x:DataType="local:TestIndex">
                <Grid Background="{x:Bind Index,Converter={StaticResource BackgroundConverter}, Mode=OneWay}" Height="50">
                </Grid>
            </DataTemplate>
        </Page.Resources>
    
        <Grid>
            <ListView ItemsSource="{x:Bind TestCollection}"
                      IsItemClickEnabled="True"
                      AllowDrop="True"
                      CanReorderItems="True"
                      IsSwipeEnabled="True"
                      ItemTemplate="{StaticResource DefaultRow}"
                      >
                <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                    </Style>
                </ListView.ItemContainerStyle>
            </ListView>
        </Grid>
    </Page>
    

    xaml.cs

    private ObservableCollection<TestIndex> TestCollection = new ObservableCollection<TestIndex>();
    public ListViewPage()
    {
        this.InitializeComponent();
        for (int i = 0; i < 10; i++)
        {
            TestCollection.Add(new TestIndex()
            {
                Index = i
            });
        }
        TestCollection.CollectionChanged += CollectionChanged;
    }
    
    private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        for (int i = 0; i < TestCollection.Count; i++)
        {
            TestCollection[i].Index = i;
        }
    }
    

    这是因为在 ListView 中拖放项目时不会触发 DragItemsCompleted 事件。因为本质上是对集合元素的删除和添加,所以需要为集合注册CollectionChanged事件。

    最好的问候。

    【讨论】:

      【解决方案2】:

      一个更简单的解决方案是这样的:

          private void SongsListView_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
          {
              for(int i = 0; i < sender.Items.Count; i++)
              {
                  var container = sender.ContainerFromIndex(i) as ListViewItem;
                  container.Background = i % 2 == 0 ? Helper.WhiteSmokeBrush : Helper.WhiteBrush;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2017-05-14
        • 1970-01-01
        • 2016-10-28
        • 2016-08-26
        • 2023-03-03
        • 2016-03-13
        • 2020-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多