我需要从后面的代码访问DataGrid的模板列中的文本,但我不知道如何.我需要将文本更改为我在SelectionChanged事件中传递给它的任何字符串.有人可以告诉我如何实现这一目标吗?我发现了一个类似的问题
here
但它没有答案.
但它没有答案.
解决方法
要在DataGrid模板列中查找控件,应使用FindChild():
public static T FindChild<T>(DependencyObject parent,string childName) where T : DependencyObject { if (parent == null) { return null; } T foundChild = null; int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < childrenCount; i++) { var child = VisualTreeHelper.GetChild(parent,i); T childType = child as T; if (childType == null) { foundChild = FindChild<T>(child,childName); if (foundChild != null) break; } else if (!string.IsNullOrEmpty(childName)) { var frameworkElement = child as FrameworkElement; if (frameworkElement != null && frameworkElement.Name == childName) { foundChild = (T)child; break; } else { foundChild = FindChild<T>(child,childName); if (foundChild != null) { break; } } } else { foundChild = (T)child; break; } } return foundChild; }
例如,我在MyDataGrid中有这个模板列:
<DataGridTemplateColumn Width="1.5*" IsReadOnly="False"> <DataGridTemplateColumn.Header> <TextBlock Text="Sample" ToolTip="{Binding Path=Text,RelativeSource={RelativeSource Self}}" FontSize="14" /> </DataGridTemplateColumn.Header> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock x:Name="MyTextBlock" Text="Hello!" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
从代码中访问它,您可以:
TextBlock MyTextBlock = FindChild<TextBlock>(MyDataGrid,"MyTextBlock"); MessageBox.Show(MyTextBlock.Text);
注意:只有在控件完全加载时才使用FindChild,否则它将找不到它并给出null.在这种情况下,我将此代码放在事件ContentRendered(Window)中,该事件表明窗口的所有内容都成功加载(即使事件MyDataGrid_Loaded无法访问MyTextBlock,因为它尚未加载):
private void Window_ContentRendered(object sender,EventArgs e) { TextBlock MyTextBlock = FindChild<TextBlock>(MyDataGrid,"MyTextBlock"); MessageBox.Show(MyTextBlock.Text); }
EDIT1:
要访问所选行的控件,将事件SelectionChanged添加到要运行的DataGrid,这将给出一个选定的行:
private void MyDataGrid_SelectionChanged(object sender,SelectionChangedEventArgs e) { try { var row_list = GetDataGridRows(MyDataGrid); foreach (DataGridRow single_row in row_list) { if (single_row.IsSelected == true) { TextBlock MyTextBlock = FindChild<TextBlock>(single_row,"MyTextBlock"); MessageBox.Show(MyTextBlock.Text); } } } catch { throw new Exception("Can't get access to DataGridRow"); } }
GetDataGridRows()的列表:
public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid) { var itemsSource = grid.ItemsSource as IEnumerable; if (null == itemsSource) { yield return null; } foreach (var item in itemsSource) { var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow; if (null != row) { yield return row; } } }
EDIT2:
public static void FindChildGroup<T>(DependencyObject parent,string childName,ref List<T> list) where T : DependencyObject { // Checks should be made,but preferably one time before calling. // And here it is assumed that the programmer has taken into // account all of these conditions and checks are not needed. //if ((parent == null) || (childName == null) || (<Type T is not inheritable from FrameworkElement>)) //{ // return; //} int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < childrenCount; i++) { // Get the child var child = VisualTreeHelper.GetChild(parent,i); // Compare on conformity the type T child_Test = child as T; // Not compare - go next if (child_Test == null) { // Go the deep FindChildGroup<T>(child,childName,ref list); } else { // If match,then check the name of the item FrameworkElement child_Element = child_Test as FrameworkElement; if (child_Element.Name == childName) { // Found list.Add(child_Test); } // We are looking for further,perhaps there are // children with the same name FindChildGroup<T>(child,ref list); } } return; }
private void Window_ContentRendered(object sender,EventArgs e) { // Create the List List<TextBlock> list = new List<TextBlock>(); // Find all elements FindChildGroup<TextBlock>(MyDataGrid,"MyTextBlock",ref list); string text = ""; // Print foreach (TextBlock elem in list) { text += elem.Text + "\n"; } MessageBox.Show(text,"Text in TextBlock"); }
一般来说,这种做法不是最好的…获取项目(如全部或选中),您可以直接联系到存储您的数据的列表(如ObservableCollection).此外,它是有用的事件,如PropertyChanged.