This is how the xaml looks like:
<ListView HorizontalContentAlignment="Stretch"
x:Name="listViewMessages"
Grid.Column="1"
ItemsSource="{x:Bind MessageViewModel.Messages}"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}"
ItemClick="listViewMessages_ItemClick">
<ListView.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Message">
<Grid HorizontalAlignment="{x:Bind Path=MineToHorizontalAlignment()}" Background="{x:Bind Path=MineBackgroundColor()}" CornerRadius="8" Margin="0,6,0,2" Padding="6">
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
...
<Button Grid.Column="5" Click="Button_Click">D</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So when I will click the button I want to get the list view item of the clicked button.
How can I achieve this?
Edit: I changed the xaml example to a more specific one.
You need to use the VisualTreeHelper Class to traverse the visual tree. Here is a C++/WinRT utility to walk the parents recursively:
template <typename T>
T GetParent(DependencyObject obj)
{
if (!obj)
return nullptr;
auto parent = Microsoft::UI::Xaml::Media::VisualTreeHelper::GetParent(obj);
if (!parent)
return nullptr;
auto parentAs = parent.try_as<T>();
if (parentAs)
return parentAs;
return GetParent<T>(parent);
}
And it's C# counterpart for what it's worth:
public static T GetParent<T>(DependencyObject obj) => (T)GetParent(obj, typeof(T));
public static object GetParent(DependencyObject obj, Type type)
{
if (obj == null)
return null;
var parent = VisualTreeHelper.GetParent(obj);
if (parent == null)
return null;
if (type.IsAssignableFrom(parent.GetType()))
return parent;
return GetParent(parent, type);
}
So you would call it like this:
void MainWindow::Button_Click(IInspectable const& sender, RoutedEventArgs const&)
{
auto listView = GetParent<Controls::ListView>(sender.try_as<DependencyObject>());
}