크로스 플랫폼 타사 레이아웃 엔진을 사용하여 UI elements
을 Visual Tree
(캔버스에 넣음)에 배치하는 앱에서 작업하고 있습니다. 내 시나리오에서는 가상화가 필요합니다. ListView
모든 항목이이 레이아웃 엔진을 통과합니다.UWP 앱에서 GetContainerForItemOverride
목록보기에서 항목을 삭제하려고 시도하기 전까지는 문제가 없습니다. 나는 내 목록보기에 대해 ListViewItem
을 반환하는 대신 GetContainerForItemOverride()를 호출 할 때 Canvas
을 반환한다는 사실에이 문제를 좁혀 냈습니다. 레이아웃 엔진이 Canvas
의 특정 좌표에 물건을 넣을 수 있도록 물론 Canvas
이 필요합니다.
아래에 아주 바보 같은 샘플이 만들어져서 내가 겪고있는 문제가 재현됩니다. 기본적으로 내가 .RemoveAt()
또는 .Remove()
을 호출하여 항목을 삭제하려고하면 .Items
에 직접 추가하는 대신 ItemsSource
을 사용하는 경우 동일한 문제가 발생하므로 InvalidCastException
이 발생합니다.
누구든지이 문제를 해결하는 방법을 알고 있습니까?
여기에 코드
<Page x:Class="Sample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sample="using:Sample">
<StackPanel>
<sample:CustomListViewCrash x:Name="MyListViewCrash">
<sample:CustomListViewCrash.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</sample:CustomListViewCrash.ItemsPanel>
</sample:CustomListViewCrash>
<Button Content="Delete" Tapped="Delete_OnTapped" />
</StackPanel>
</Page>
그리고
public sealed partial class MainPage
{
public MainPage()
{
InitializeComponent();
MyListViewCrash.Items.Add("blah blah");
}
private void Delete_OnTapped(object sender, TappedRoutedEventArgs e)
{
if (MyListViewCrash.Items.Count > 0)
{
MyListViewCrash.Items.RemoveAt(0);
}
}
}
public class CustomListViewCrash : ListView
{
protected override DependencyObject GetContainerForItemOverride()
{
var canvas = new Canvas
{
Width = 100,
Height = 50
};
canvas.Children.Add(new Button());
return canvas;
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
var canvas = (Canvas) element;
var button = (Button) canvas.Children[0];
button.Content = item;
base.PrepareContainerForItemOverride(element, item);
}
}
뒤에 코드입니다 그리고 여기에 예외에 대한 정보입니다 :
System.InvalidCastException occurred
HResult=0x80004002
Message=Specified cast is not valid.
Source=System.Private.CoreLib
StackTrace:
at System.Runtime.InteropServices.WindowsRuntime.IVector`1.RemoveAt(UInt32 index)
at System.Runtime.InteropServices.WindowsRuntime.VectorToListAdapter.RemoveAtHelper[T](IVector`1 _this, UInt32 index)
at System.Runtime.InteropServices.WindowsRuntime.VectorToListAdapter.RemoveAt[T](Int32 index)
at ReactiveDelete.MainPage.Delete_OnTapped(Object sender, TappedRoutedEventArgs e) in MainPage.xaml.cs:line 31
예 당신이 말한 일을하면 충돌을 타격하지 않는 문제를 해결한다. 비록 당신의 접근 방식으로 다른 렌더링 문제 (깜박임)를보고 있습니다. 하지만 그게 내 애플 리케이션과 관련이있을 수 있으므로 솔루션으로 표시하는 것 같아요. 감사. –