简体   繁体   English

拖放后的UWP ListView更新行背景

[英]UWP ListView Update Row Background After Drag and Drop

I am currently doing this to make my ListView have an alternating row background. 我目前正在这样做,以使我的ListView具有交替的行背景。

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

Additionally, I also allow my ListView to be able to drag and drop items. 此外,我还允许ListView拖放项目。 However, the row color doesn't update its color after dropping even though I do this: 但是,即使执行此操作,行颜色在删除后也不会更新其颜色:

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

meaning that my ListView does not have an alternating background after drag and drop. 表示我的ListView拖放后没有交替的背景。

How should I update its background? 我应该如何更新其背景?

ContainerContentChanging is the initialization rendering, and UpdateLayout is used to ensure that the element has been rendered instead of re-rendering the entire list. ContainerContentChanging是初始化呈现,而UpdateLayout用于确保元素已呈现,而不是重新呈现整个列表。

For your situation, I recommend using IValueConverter for background color conversion. 根据您的情况,我建议使用IValueConverter进行背景颜色转换。 You can add an Index property to the data type to identify where it is now. 您可以将Index属性添加到数据类型以标识它现在的位置。

This is a simple example: 这是一个简单的示例:

TestModel.cs 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 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 a

<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 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;
    }
}

This is because the DragItemsCompleted event is not triggered when you drag and drop items inside the ListView. 这是因为在ListView内拖放项目时不会触发DragItemsCompleted事件。 Because it is essentially the deletion and addition of collection elements, you need to register the CollectionChanged event for the collection. 因为本质上是删除和添加集合元素,所以您需要为CollectionChanged注册CollectionChanged事件。

Best regards. 最好的祝福。

An easier solution is this: 一个更简单的解决方案是:

    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;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM