Wpf Datagrid 操作总结

1. 行选中时,.SelectedIndex可以获取行索引,多行选中可用 SelectedItems

2.单元格选中时,获取行索引可以用以下(Grid为DataGrid的对象)

DataGridCellInfo selectedCell = Grid.SelectedCells.FirstOrDefault();
//没有选中Record
if (selectedCell == null || selectedCell.Column == null)
    return;
int index = Grid.Items.IndexOf(selectedCell.Item);

3.替换某个单元格中TextBlock为Combox

DataGridRow row = (DataGridRow)Grid.ItemContainerGenerator.ContainerFromIndex(Index);
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
//这行代码是通过行得到单元格
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(Col);
//这行代码是通过index得到具体的单元格

FrameworkElementFactory factory = new FrameworkElementFactory(typeof(StackPanel), "StackPanelName");
factory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

FrameworkElementFactory buttonComboBox = new FrameworkElementFactory(typeof(ComboBox), "ComboxName");

buttonComboBox.SetValue(ComboBox.SelectedIndexProperty, 0);
buttonComboBox.SetValue(ComboBox.DisplayMemberPathProperty, "Data");
buttonComboBox.SetValue(ComboBox.ItemsSourceProperty, filterDataList);
buttonComboBox.SetValue(ComboBox.WidthProperty, cell.ActualWidth);
buttonComboBox.SetValue(ComboBox.FontSizeProperty, cell.FontSize - 3);

buttonComboBox.AddHandler(
      ComboBox.LoadedEvent,
      new RoutedEventHandler(
      (s, ea) =>
      {
         ComboBox comboBox = (ComboBox)s;
         comboBox.DropDownClosed += ComboBox_DropDownClosed;
       }));

factory.AppendChild(buttonComboBox);

DataTemplate dataTemplate = new DataTemplate();
dataTemplate.VisualTree = factory;

if(cell.ContentTemplate == null)
{
    cell.ContentTemplate = dataTemplate;
    //获取元素,并设置焦点
            ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(cell);
            bool ret = myContentPresenter.ApplyTemplate();

            DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
            ComboBox myCombox = (ComboBox)myDataTemplate.FindName("ComboxName", myContentPresenter);
           myCombox.Focus();

}

 

private childItem FindVisualChild<childItem>(DependencyObject obj)
            where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                    return (childItem)child;
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }

 

4. ItemContainerGenerator顺序为Datagrid显示的顺序,排序后也与之对应

 

5.如果用FrameworkElementFactory生成Datagrid列,但是没有用ApplyTemplate(), 在用myDataTemplate.FindName是找不到的,可以用

DataGridTemplateColumn templeColumn = Grid_Holes.Columns[displayIndex] as DataGridTemplateColumn;
if (templeColumn == null) return;
templeColumn.CellTemplate.LoadContent();

进行查找

 

6.Datagrid 已知行列,获取DataGridCell

DataGridCell dataGridCell = GetDataGridCellWithScroll(dataGrid, row, column);

/// <summary>
        /// 获取指定的单元格时是否允许滚动
        /// </summary>
        /// <param name="dataGrid">DataGrid对象</param>
        /// <param name="rowIndex">行索引</param>
        /// <param name="columnIndex">列索引</param>
        /// <param name="needScroll">不在可见范围内是否允许滚动查找</param>
        /// <returns></returns>
        public static DataGridCell GetDataGridCellWithScroll(DataGrid dataGrid, int rowIndex, int columnIndex, bool needScroll = false)
        {
            try
            {
                DataGridRow rowContainer = GetDataGridRow(dataGrid, rowIndex, needScroll);
                if (rowContainer != null)
                {
                    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
                    //这行代码是通过行得到单元格

                    DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
                    //这行代码是通过index得到具体的单元格

                    if (cell == null)
                    {
                        if (needScroll)
                        {
                            dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[columnIndex]);
                            cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
                        }
                    }
                    return cell;
                }
            }
            catch
            {
                return null;
            }
            return new DataGridCell();
        }
        public static DataGridRow GetDataGridRow(DataGrid dataGrid, int index, bool needScroll = false)
        {
            if (index >= dataGrid.Items.Count)
            {
                throw new IndexOutOfRangeException(String.Format("Index {0} is out of range.", index));
            }

            DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
            if (row == null)
            {
                if (needScroll)
                {
                    // may be virtualized, bring into view and try again
                    dataGrid.ScrollIntoView(dataGrid.Items[index]);
                    WaitFor(TimeSpan.Zero, DispatcherPriority.SystemIdle);
                    row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
                }
            }

            return row;
        }

        public static void WaitFor(TimeSpan time, DispatcherPriority priority)
        {
            DispatcherTimer timer = new DispatcherTimer(priority);
            timer.Tick += new EventHandler(OnDispatched);
            timer.Interval = time;
            DispatcherFrame dispatcherFrame = new DispatcherFrame(false);
            timer.Tag = dispatcherFrame;
            timer.Start();
            Dispatcher.PushFrame(dispatcherFrame);
        }
        public static void OnDispatched(object sender, EventArgs args)
        {
            DispatcherTimer timer = (DispatcherTimer)sender;
            timer.Tick -= new EventHandler(OnDispatched);
            timer.Stop();
            DispatcherFrame frame = (DispatcherFrame)timer.Tag;
            frame.Continue = false;
        }

        public static T GetVisualChild<T>(Visual parent) where T : Visual
        {
            T childContent = default(T);
            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                childContent = v as T;
                if (childContent == null)
                {
                    childContent = GetVisualChild<T>(v);
                }
                if (childContent != null)
                {
                    break;
                }
            }
            return childContent;
        }

        public static List<T> GetChildObjects<T>(DependencyObject obj, string name) where T : FrameworkElement
        {
            DependencyObject child = null;
            List<T> childList = new List<T>();

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);

                if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
                {
                    childList.Add((T)child);
                }
                childList.AddRange(GetChildObjects<T>(child, name));
            }
            return childList;
        }

        public static T GetChildObject<T>(DependencyObject parentObj, string name) where T : FrameworkElement
        {

            DependencyObject child = null;
            T grandChild = null;


            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parentObj); i++)
            {
                child = VisualTreeHelper.GetChild(parentObj, i);

                if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
                {
                    return (T)child;
                }
                else
                {
                    grandChild = GetChildObject<T>(child, name);
                    if (grandChild != null)

                        return grandChild;
                }
            }
            return null;
        }

 

7.已知DataGridRow,获取行号

public static int FindRowIndex(DataGridRow row)
        {
            DataGrid dataGrid = ItemsControl.ItemsControlFromItemContainer(row) as DataGrid;

            int index = dataGrid.ItemContainerGenerator.IndexFromContainer(row);

            return index;
        }

 

8.由DataGridCell 获取TextBlock

TextBlock textBlock = (dataGrid.Columns[column].GetCellContent(dataGrid.Items[row]) as TextBlock);
TextBlock tb = GetVisualChild<TextBlock>(dataGridCell);

 

posted on 2023-05-05 14:48  wu.g.q  阅读(226)  评论(0编辑  收藏  举报

导航