嗨,我在 itemscontrol 的数据模板中只有几个文本框。当我将 itemcontrols 绑定到可观察集合时,我得到两个文本框。但我需要根据每个文本框进行一些操作,我想使用一些 id 分别找到每个文本框。
任何人都可以帮助如何在 WPF 中的 itemscontrol 中找到控件。
嗨,我在 itemscontrol 的数据模板中只有几个文本框。当我将 itemcontrols 绑定到可观察集合时,我得到两个文本框。但我需要根据每个文本框进行一些操作,我想使用一些 id 分别找到每个文本框。
任何人都可以帮助如何在 WPF 中的 itemscontrol 中找到控件。
使用 ItemContainerGenerator 您可以获得项目的生成容器并向下遍历可视化树以找到您的 TextBox。对于 ItemsControl,它将是 ContentPresenter,但 ListBox 将返回 ListBoxItem,ListView 将返回 ListViewItem,等等。
ContentPresenter cp = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter;
TextBox tb = FindVisualChild<TextBox>(cp);
if (tb != null)
{
// do something with tb
}
public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
return (T)child;
}
T childItem = FindVisualChild<T>(child);
if (childItem != null) return childItem;
}
}
return null;
}
如果需要,您也可以通过索引获取容器
itemsControl.ItemContainerGenerator.ContainerFromIndex(0);
谢谢布莱斯,我试着勾选向上箭头,但它说我的评分太低了!对不起!
我修改了代码以返回给定类型的所有子项的所有列表,因为这是我需要的,并且认为其他人可能会发现它有用。
再次感谢布莱斯,真的很有帮助 - 对评级的事情感到抱歉!
public static List<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
List<T> list = new List<T>();
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
list.Add((T)child);
}
List<T> childItems = FindVisualChildren<T>(child);
if (childItems != null && childItems.Count() > 0)
{
foreach (var item in childItems)
{
list.Add(item);
}
}
}
}
return list;
}
您可能想尝试使用VisualTreeHelper。ItemsControl 本身的属性只允许您获取其绑定的数据,而不是用于可视化数据的模板实例,而 VisualTreeHelper 允许您在 WPF 呈现它时浏览可视化树。
如果您(递归地)遍历父 ItemControl 的可视子项,则定位您在屏幕上看到的文本框应该没有任何困难。
另一个例子:
private void DataGridBank_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
try
{
switch (e.Key)
{
case Key.Down:
if ((DataGridBank.SelectedIndex + 1) <= DataGridBank.Items.Count)
{
DataGridBank.SelectedIndex = DataGridBank.SelectedIndex + 1;
FocusCell();
}
break;
case Key.Up:
if ((DataGridBank.SelectedIndex - 1) >= 0)
{
DataGridBank.SelectedIndex = DataGridBank.SelectedIndex - 1;
FocusCell();
}
break;
case Key.Enter:
case Key.Tab:
FocusCell();
break;
}
}
catch (Exception ex)
{
}
}
private void DataGridBank_Loaded(object sender, RoutedEventArgs e)
{
try
{
if (DataGridBank.Items.Count > 0)
{
DataGridBank.SelectedIndex = 0;
FocusCell();
}
}catch(Exception ex)
{
}
}
private void FocusCell()
{
var selectedRow = (DataGridRow)DataGridBank.ItemContainerGenerator.ContainerFromItem(DataGridBank.SelectedItem);
var textImport = FindVisualChild<TextBox>(selectedRow);
textImport.Focus();
textImport.SelectAll();
}
public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
return (T)child;
}
T childItem = FindVisualChild<T>(child);
if (childItem != null) return childItem;
}
}
return null;
}
如果您有数据网格和模板列,其中包含数据模板,您可以使用以下代码示例
<DataGridTemplateColumn x:Name="photoPathColumn" Header="{x:Static resx:FrmResource.Photo}">
<DataGridTemplateColumn.CellEditingTemplate x:Uid="keyelm">
<DataTemplate x:Name="dodo">
<StackPanel Orientation="Horizontal" Height="Auto">
<TextBlock x:Name="photo" x:Uid="imageFile" Text="{Binding Path=PhotoPath}" />
<Button x:Name="Browse" Content="..." Click="Browse_Click" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
photoPathColumn.CellEditingTemplate.FindName("photo",photoPathColumn.GetCellContent(CustomersDataGrid.CurrentItem))