如何在复选框事件中访问嵌套列表视图数据模板中的标签名称
how to access label name in nested listview datatemplate on a check box event
我已经用名称定义了一个标签,我正在尝试访问它,但没有成功。让我用我的代码解释我的问题。
<ListView Name="gridListView" ItemsSource="{Binding... }">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Focusable" Value="false"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel Orientation="Vertical">
<Label x:Name="vLabel" Content="{Binding VCValue}"/>
<ListView Name="checkBoxListView" ItemsSource="{Binding CList}">
<ListView.ItemTemplate>
<DataTemplate>
<CheckBox Margin="5" Click="CheckBox_Click" IsChecked="{Binding SelectedValue, Mode=TwoWay}" Content="{Binding Current, Mode=OneWay }"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
在上面的代码中,我有两个listview,gridListView和checkBoxListView。在这里,当单击复选框中的值之一(位于 checkBoxListView 内)时,我想访问位于 gridListView 的数据模板内的标签 vLabel。
我知道它不能直接访问,因为它在数据模板中,所以我按照其他论坛中的建议尝试了下面的代码,但 gridListView.SelectedIndex 始终是 -1,所以我知道我没有做正确的事情。当我刚刚将 gridListView.SelectedIndex 硬编码为索引 0、1 或 2 时,它为我提供了正确的 vLabel 值,因此如果 gridListView.SelectedIndex 正确,下面的代码将起作用。
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox chk =(CheckBox)sender;
int index = gridListView.Items.IndexOf(chk.DataContext);
ListViewItem item = gridListView.ItemContainerGenerator.ContainerFromIndex(gridListView.SelectedIndex) as ListViewItem;
if (item!=null)
{
//get the item's template parent
ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(item);
DataTemplate dataTemplate = gridListView.ItemTemplate;
if (dataTemplate != null && templateParent != null)
{
var lab = dataTemplate.FindName("vLabel", templateParent) as Label;
var v = lab.Content;
}
}
private static T GetFrameworkElementByName<T>(FrameworkElement referenceElement) where T : FrameworkElement
{
//I can post this function if need be
....
}
感谢任何帮助我访问 vLabel 的帮助。
提前致谢
您正在将 focusable 设置为 false,因此您无法 select 单击该项目。 checkbox-checked 也发生在 selection 之前,即使您将 focusable 设置为 true,所以 selected 索引仍然是 -1。
您可以像这样简单地找到您的标签:
public Label FindLabel(CheckBox checkBox)
{
var listView = VisualTreeHelper.GetParent(checkBox);
while (listView.GetType() != typeof(ListView))
{
listView = VisualTreeHelper.GetParent(listView);
}
return (listView as FrameworkElement).FindName("vLabel") as Label;
}
但我建议您告诉我们您想要实现的目标,因为这似乎不是一个干净的解决方案。
你能不能在你的 StackPanel 上做这个:
<StackPanel CheckBox.Checked="CheckBox_Click" Orientation="Vertical">
然后按如下方式访问您想要的两个属性:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
var outerItem = (sender as FrameworkElement).DataContext;
var innerItem = (e.OriginalSource as FrameworkElement).DataContext;
}
然后为所欲为?
感谢您的指导。我确实从 Milan 的代码中得到提示来解决我的问题。在这里,我试图获取 listviewItem(即 stackpanel)的引用父级,然后访问其子级。在我的例子中,索引 0 处的堆栈面板子项是 Label,索引 1 处是 ListView。因此,然后我通过 visualtreehelper 在索引 0 处获取对其子项的引用,这是我需要访问的。所以这是代码片段。
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
//to access parent of the checkbox
ListViewItem listViewItem =
GetVisualAncestor<ListViewItem>((DependencyObject)sender);
//to access parent of the listViewItem(which is parent of checkbox)
StackPanel stackPanel =
GetVisualAncestor<StackPanel>((DependencyObject)listViewItem);
int childCount = VisualTreeHelper.GetChildrenCount(stackPanel);
//to access child of stackpanel to access the current vLabel
var vValue = VisualTreeHelper.GetChild(stackPanel, 0) as Label;
}
private static T GetVisualAncestor<T>(DependencyObject o)where T : DependecyObject
{
...
}
我已经用名称定义了一个标签,我正在尝试访问它,但没有成功。让我用我的代码解释我的问题。
<ListView Name="gridListView" ItemsSource="{Binding... }">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Focusable" Value="false"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel Orientation="Vertical">
<Label x:Name="vLabel" Content="{Binding VCValue}"/>
<ListView Name="checkBoxListView" ItemsSource="{Binding CList}">
<ListView.ItemTemplate>
<DataTemplate>
<CheckBox Margin="5" Click="CheckBox_Click" IsChecked="{Binding SelectedValue, Mode=TwoWay}" Content="{Binding Current, Mode=OneWay }"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
在上面的代码中,我有两个listview,gridListView和checkBoxListView。在这里,当单击复选框中的值之一(位于 checkBoxListView 内)时,我想访问位于 gridListView 的数据模板内的标签 vLabel。 我知道它不能直接访问,因为它在数据模板中,所以我按照其他论坛中的建议尝试了下面的代码,但 gridListView.SelectedIndex 始终是 -1,所以我知道我没有做正确的事情。当我刚刚将 gridListView.SelectedIndex 硬编码为索引 0、1 或 2 时,它为我提供了正确的 vLabel 值,因此如果 gridListView.SelectedIndex 正确,下面的代码将起作用。
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox chk =(CheckBox)sender;
int index = gridListView.Items.IndexOf(chk.DataContext);
ListViewItem item = gridListView.ItemContainerGenerator.ContainerFromIndex(gridListView.SelectedIndex) as ListViewItem;
if (item!=null)
{
//get the item's template parent
ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(item);
DataTemplate dataTemplate = gridListView.ItemTemplate;
if (dataTemplate != null && templateParent != null)
{
var lab = dataTemplate.FindName("vLabel", templateParent) as Label;
var v = lab.Content;
}
}
private static T GetFrameworkElementByName<T>(FrameworkElement referenceElement) where T : FrameworkElement
{
//I can post this function if need be
....
}
感谢任何帮助我访问 vLabel 的帮助。
提前致谢
您正在将 focusable 设置为 false,因此您无法 select 单击该项目。 checkbox-checked 也发生在 selection 之前,即使您将 focusable 设置为 true,所以 selected 索引仍然是 -1。
您可以像这样简单地找到您的标签:
public Label FindLabel(CheckBox checkBox)
{
var listView = VisualTreeHelper.GetParent(checkBox);
while (listView.GetType() != typeof(ListView))
{
listView = VisualTreeHelper.GetParent(listView);
}
return (listView as FrameworkElement).FindName("vLabel") as Label;
}
但我建议您告诉我们您想要实现的目标,因为这似乎不是一个干净的解决方案。
你能不能在你的 StackPanel 上做这个:
<StackPanel CheckBox.Checked="CheckBox_Click" Orientation="Vertical">
然后按如下方式访问您想要的两个属性:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
var outerItem = (sender as FrameworkElement).DataContext;
var innerItem = (e.OriginalSource as FrameworkElement).DataContext;
}
然后为所欲为?
感谢您的指导。我确实从 Milan 的代码中得到提示来解决我的问题。在这里,我试图获取 listviewItem(即 stackpanel)的引用父级,然后访问其子级。在我的例子中,索引 0 处的堆栈面板子项是 Label,索引 1 处是 ListView。因此,然后我通过 visualtreehelper 在索引 0 处获取对其子项的引用,这是我需要访问的。所以这是代码片段。
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
//to access parent of the checkbox
ListViewItem listViewItem =
GetVisualAncestor<ListViewItem>((DependencyObject)sender);
//to access parent of the listViewItem(which is parent of checkbox)
StackPanel stackPanel =
GetVisualAncestor<StackPanel>((DependencyObject)listViewItem);
int childCount = VisualTreeHelper.GetChildrenCount(stackPanel);
//to access child of stackpanel to access the current vLabel
var vValue = VisualTreeHelper.GetChild(stackPanel, 0) as Label;
}
private static T GetVisualAncestor<T>(DependencyObject o)where T : DependecyObject
{
...
}