Sun*_*Sun 3 xaml winrt-xaml windows-store-apps windows-8.1
我有一个简单的ListView,没有项目模板和SelectionChanged事件设置:
<ListView x:Name="list1" HorizontalAlignment="Left"
Height="556"
Margin="209,93,0,0"
VerticalAlignment="Top"
Width="1033"
SelectionChanged="list1_SelectionChanged" />
private void list1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var container = (sender as ListView).ContainerFromItem(e.AddedItems.First());
var presenter = VisualTreeHelper.GetChild(container, 0);
}
Run Code Online (Sandbox Code Playgroud)
我还有一个测试类如下:
class Test
{
public string FirstName { get; set; }
public string Surname { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在在页面的构造函数中,我有以下代码创建Test项的ObservableCollection,添加一些,然后将其设置为ListView的ItemSource:
ObservableCollection<Test> testCollection;
public MainPage()
{
this.InitializeComponent();
testCollection = new ObservableCollection<Test>();
testCollection.Add(new Test { FirstName = "Bob", Surname = "Smith1" });
testCollection.Add(new Test { FirstName = "Bob", Surname = "Smith2" });
testCollection.Add(new Test { FirstName = "Bob", Surname = "Smith3" });
list1.ItemsSource = testCollection;
}
Run Code Online (Sandbox Code Playgroud)
现在,当我在列表中选择一个项目并激活SelectionChanged事件时,容器变量按预期包含ListViewItem.
现在,我也在表单上有按钮,这里是按钮点击事件:
private void Button_Click(object sender, RoutedEventArgs e)
{
testCollection.Add(new Test { FirstName = "Bob", Surname = "Smith4" });
list1.SelectedIndex = list1.Items.Count - 1;
}
Run Code Online (Sandbox Code Playgroud)
最后一行选择新项目并触发SelectionChanged事件,但这次容器变量为null.
任何人都可以告诉我为什么这是空的,我该如何绕过这个?
谢谢
Jer*_*xon 10
我可以告诉你.
你在这里遇到的是时间问题.您认为可以多快将项目添加到集合中?快 - 只有一两毫秒.您认为ListView设置SelectedItem房产和SelectionChanged举办活动需要多快?快 - 一毫秒或两秒.但是,您认为ListView在屏幕上实际渲染新项目并为其生成容器需要多快?很长一段时间 - 比如10到100毫秒,取决于复杂性DataTemplate.
我意识到你的测试没有设置ItemTemplate,我假设你这样做,假设它会渲染得更快 - 也许是即时的.但DataTemplate每个都有默认值ItemsControl.而且,即使DataTemplate像内置的一样简单,仍然需要花费更多的时间来推进单个C#线.
这段代码将说明我的意思:
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var items = Enumerable.Range(1, 10)
.Select(x => new Item { FirstName = "Bob", LastName = "Smith" + x.ToString() });
var list = new ObservableCollection<Item>(items);
MyListView.ItemsSource = list;
var item = new Item { FirstName = "Jerry", LastName = "Nixon" };
list.Add(item);
await Task.Delay(1000);
MyListView.SelectedItem = item;
}
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
System.Diagnostics.Debug.Assert(e.AddedItems.Any());
var listview = sender as ListView;
var container = listview.ContainerFromItem(e.AddedItems.First());
System.Diagnostics.Debug.Assert(container != null);
var presenter = VisualTreeHelper.GetChild(container, 0);
System.Diagnostics.Debug.Assert(presenter != null);
}
Run Code Online (Sandbox Code Playgroud)
请注意
Delay代码; 这就是它的工作原理.
希望您简化了问题,这就是您在代码隐藏而不是在视图模型中进行工作的原因.精细.首先,确保并处理这种类型的逻辑,Loaded这样您就可以确信它ListView甚至可用.然后,再次在视图模型中执行此操作.
所以,我已经回答了你的问题.为什么?因为时间安排.
在我看来它可能都是通过一个简单的视图模型解决的,但话又说回来,我只知道你的情况.也许有一些我没看到的东西.
祝你好运!
| 归档时间: |
|
| 查看次数: |
2322 次 |
| 最近记录: |