在 WINUI3 中获取元素根的视图模型上下文



我有一个页面,其中包含绑定到ViewModel中对象的ListView x。此对象包含一个对象列表(时间戳(,其中包含一个主题列表,其中包含另一个对象的列表。我在两个列表视图中展示数据,一个在另一个里面。

<ListView
x:Name="primaryList" // for exemplification purposes
ItemsSource="{x:Bind ViewModel.VideoProject.TimeStamps, Mode=OneWay}"
ItemClick='{x:Bind ViewModel.ListViewTimeStamps_ItemClick, Mode=OneWay}'>

ListView包含另一个ListView 的DataTemplate

<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Spacing="5">
<TextBlock Text="{Binding Id}"
FontSize="15"
HorizontalAlignment="Left"
FontWeight="Bold" />

<ListView ItemsSource="{Binding Subjects}"
x:Name="secondaryList"
SelectionMode="Multiple">
<ListView.ItemTemplate>
....

第二个ListView后面跟着另一个相同的结构。

我的目标是将第二个ListView ItemClickEvent绑定到ViewModel中的ListViewTimeStamps_ItemClick方法,因为我需要secondary ListView持有的对象(Subject(中包含的数据。我可以尝试将数据模板上下文设置为ViewModel,但这会破坏Subject绑定。

我发现了很多关于这个主题的问题,但与WPF不同的是,没有AncestorType来获取上层树引用。

Obs:我的项目基于模板模型,该模型创建了以ViewModel为属性的XAML.cs。我还没有在XAML页面上设置DataContext,因为我可以在没有显式设置的情况下将视图模型正常地x:绑定到页面元素。

有没有一种方法可以在不使用附加属性的情况下完成?非常感谢。

由于在WinUI中不支持设置RelativeSourceAncestorType属性,因此如果不编写一些代码,就无法在纯XAML中实现这一点。

你可以按照这里的建议和示例实现一个附加的bevaiour:

public static class AncestorSource
{
public static readonly DependencyProperty AncestorTypeProperty =
DependencyProperty.RegisterAttached(
"AncestorType",
typeof(Type),
typeof(AncestorSource),
new PropertyMetadata(default(Type), OnAncestorTypeChanged)
);
public static void SetAncestorType(FrameworkElement element, Type value) =>
element.SetValue(AncestorTypeProperty, value);
public static Type GetAncestorType(FrameworkElement element) =>
(Type)element.GetValue(AncestorTypeProperty);
private static void OnAncestorTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement target = (FrameworkElement)d;
if (target.IsLoaded)
SetDataContext(target);
else
target.Loaded += OnTargetLoaded;
}
private static void OnTargetLoaded(object sender, RoutedEventArgs e)
{
FrameworkElement target = (FrameworkElement)sender;
target.Loaded -= OnTargetLoaded;
SetDataContext(target);
}
private static void SetDataContext(FrameworkElement target)
{
Type ancestorType = GetAncestorType(target);
if (ancestorType != null)
target.DataContext = FindParent(target, ancestorType);
}
private static object FindParent(DependencyObject dependencyObject, Type ancestorType)
{
DependencyObject parent = VisualTreeHelper.GetParent(dependencyObject);
if (parent == null)
return null;
if (ancestorType.IsAssignableFrom(parent.GetType()))
return parent;
return FindParent(parent, ancestorType);
}
}

到目前为止还没有替换AncestorType?

否。不在XAML中。

最新更新