我正在使用ListView并将ItemsSources设置为Message对象的ObservableCollection。 ListViewItem的DataTemplate包含一个自定义控件。我在自定义控件上定义了一个Message属性,并将此自定义控件上的Message属性绑定到ListViewItem的dataContext。当在自定义控件上触发加载的事件时,我想将其Message上的ReceivedDate集与此ListViewItem的兄弟上设置的ReceivedDate进行比较。由于在Loaded事件被触发时在某些ListViewItem上设置了Message属性而没有在某些事件上设置,因此这种方法不能始终如一地工作。
示例:
<local:ListView x:Name="MyMessagesView"
Visibility="Collapsed"
ItemsSource="{Binding Messages}"
ItemContainerStyle="{StaticResource AppListViewItemStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<dm:MyScreenRow Message="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</local:ListView>
在我的CustomControl背后的代码中,我处理Loaded事件。我想比较当前ListViewItem上的ReceivedTime属性和它以前的兄弟,并在ListViewItem中显示一个子元素。 Loaded事件不是处理这个问题的正确位置吗?如果没有,有关如何处理这个的任何建议吗?
public MyScreenRow()
{
this.InitializeComponent();
this.Loaded += MyScreenRow_Loaded;
}
private static void MyScreenRow_Loaded(object sender, RoutedEventArgs e)
{
MyScreenRow screenRow = sender as MyScreenRow;
if (screenRow.Message == null)
{
return;
}
ListViewItemPresenter presenter = (ListViewItemPresenter)VisualTreeHelper.GetParent(screenRow);
if (presenter != null)
{
ListViewItem currentViewItem = (ListViewItem)VisualTreeHelper.GetParent(presenter);
if (currentViewItem != null)
{
ListView listView = (ListView)ItemsControl.ItemsControlFromItemContainer(currentViewItem);
if (listView != null)
{
int indexOfCurrentContainer = listView.IndexFromContainer(currentViewItem);
if (indexOfCurrentContainer == 0)
{
screenRow.GroupHeader.Visibility = Visibility.Visible;
}
else
{
// Get the previous container info
ListViewItem previousViewItem = (ListViewItem)listView.ContainerFromIndex(indexOfCurrentContainer - 1);
if (previousViewItem != null)
{
MyScreenRow previousScreenRow = (MyScreenRow)previousViewItem.ContentTemplateRoot;
if (previousScreenRow != null
&& previousScreenRow.Message != null
&& previousScreenRow.Message.ReceivedTimeUtc != null)
{
if (screenRow.Message != null
&& screenRow.Message.ReceivedTimeUtc != null)
{
if (previousScreenRow.Message.ReceivedTimeUtc.Date.CompareTo(screenRow.Message.ReceivedTimeUtc.Date) != 0)
{
screenRow.GroupHeader.Visibility = Visibility.Visible;
}
}
}
}
}
}
}
}
}
答案 0 :(得分:0)
是..因为您猜测在加载的事件中执行此操作将无法工作,因为加载的事件仅被触发一旦listview首次实例化并加载了一些元素后,它就不会被触发。
我强烈建议您使用LayoutUpdated事件。 这是UIElement的一部分,因此windows宇宙中的每个控件都必须拥有它。
在布局更改时触发..如果列表中添加或删除新项目,则会触发..
现在更有趣的部分..如果您不想一次性完成所有控件,那么您可以使用ContainerContentChanging这将允许您仅对视图中的项目应用更改。
<ListView LayoutUpdated="ListView_LayoutUpdated" ContainerContentChanging="ListView_ContainerContentChanging"/>