問題是listview使用了虛擬化,當item改變外觀時,list重繪 后依然存在。這是微軟工程師的回答
這是由 ListView 的默認面板 (ItemsStackPanel) 的虛擬化特性引起的。它本質上重用了相同的 ListViewItem(容器),當它重用它們時,它可能處于不正確的狀態。當您使用堆疊面板時,沒有虛擬化并且每個專案都有一個容器(沒有重用),您可以想象,如果串列中有很多專案,這會非常耗時。您可以嘗試使用 PrepareContainerForItemOverride、ClearContainerForItemOverride 在它們被重用之前清除 ListViewItem 的狀態。更好的是使用 ContainerContentChanging 事件并在那里進行,這樣您就不需要派生型別。
不幸的是,我找不到使用PrepareContainerForItemOverride、ClearContainerForItemOverride和ContainerContentChanging方法的示例。
如何清除 ContainerContentChanging 中 ListViewItem 的狀態?
更新:
用戶控制元件:
<Grid>
<SwipeControl x:Name="ListViewSwipeContainer">
<Grid VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock
Margin="10,5,200,5"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="18"
Text="{Binding ElementName=subsceneView, Path=Title}"
TextWrapping="Wrap"/>
<AppBarButton
Name="OpenFolderButton"
Grid.RowSpan="2"
MinWidth="75"
Margin="10,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Click="OpenFolderButton_Click"
Icon="OpenLocal"
IsTabStop="False"
Label="Open Folder"
Visibility="Collapsed"/>
<AppBarButton
Name="DownloadHoverButton"
Grid.RowSpan="2"
Margin="10,0,10,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Click="DownloadHoverButton_Click"
Icon="Download"
IsTabStop="False"
Label="Download"
Visibility="Collapsed"/>
</Grid>
</SwipeControl>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="HoveringStates">
<VisualState x:Name="HoverButtonsHidden"/>
<VisualState x:Name="HoverButtonsShown">
<VisualState.Setters>
<Setter Target="DownloadHoverButton.Visibility" Value="Visible"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
后面的代碼:
public sealed partial class SubsceneUserControl : UserControl
{
#region DependencyProperty
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(SubsceneUserControl),
new PropertyMetadata(string.Empty));
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
#endregion
public SubsceneUserControl()
{
this.InitializeComponent();
}
private void UserControl_PointerEntered(object sender, PointerRoutedEventArgs e)
{
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse ||
e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Pen)
{
VisualStateManager.GoToState(sender as Control, "HoverButtonsShown", true);
}
}
private void UserControl_PointerExited(object sender, PointerRoutedEventArgs e)
{
VisualStateManager.GoToState(sender as Control, "HoverButtonsHidden", true);
}
private void OpenFolderButton_Click(object sender, RoutedEventArgs e)
{
}
private void DownloadHoverButton_Click(object sender, RoutedEventArgs e)
{
OpenFolderButton.Visibility = Visibility.Visible;
DownloadHoverButton.Visibility = Visibility.Collapsed;
}
}
這是我的串列視圖
<ListView
x:Name="listv"
ItemsSource="{x:Bind Subtitles, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:SubsceneDownloadModel">
<local:SubsceneUserControl Title="{x:Bind Title}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
private void AddItems()
{
Subtitles?.Clear();
for (int i = 0; i < 10; i )
{
Subtitles.Add(new SubsceneDownloadModel { Title = "Test " i });
}
}
uj5u.com熱心網友回復:
ListViewItem 被重用前的狀態
對于這種情況,更好的方法是使用 mvvm 系結并實作INotifyPropertyChanged模型類。有關更多詳細資訊,請參閱深入資料系結。
例如
模型類
public class Model : INotifyPropertyChanged
{
public Model(string name)
{
this.Name = name;
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
NotifyPropertyChanged();
}
}
private bool _visible;
public bool Visible
{
get => _visible;
set
{
_visible = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
// PropertyChanged is always null.
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
xml
<ListView x:Name="MyList">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<SymbolIcon
x:Name="MySbl"
HorizontalAlignment="Right"
Symbol="Accept"
Visibility="{Binding Visible}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
用法
MyList.ItemsSource = new ObservableCollection<Model> {
new Model("hello"),
new Model("hello1"),
new Model("hello2"),
new Model("hello3"),
new Model("hello4"),
new Model("hello5"),
new Model("hello6"),
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313963.html
