有没有办法直接访问和操作指定DataGrid中的DataGridCell? C# Visual Studio 2015 社区

Is there a way to directly access and manipulate a DataGridCell in a specified DataGrid? C# Visual Studio 2015 Community

有没有办法直接访问和操作指定DataGrid中的DataGridCell? C# Visual Studio 2015 社区

我想访问特定的 DataGridCells,最好使用行和列,验证内容并更改一些属性。一旦我能到达牢房,我就可以做所有剩下的事情。我一直在使用 VisualTreeHelper 并且几乎可以到达那里。我写 "almost" 是因为出于某种原因,如果我在我的两个步骤之间插入 MessageBox.Show() 一切正常,除了我有一个我不想要的消息框。具体来说,我正在用一组数据填充数据网格,并希望更改具有与另一组数据匹配的数据的每个单元格的背景和前景。

我在使用消息框、控制台写入以及本地和监视变量之间进行调试。我发现如果没有消息框,我的 DataGridRowPresenter 会显示 0 个子项并且无法满足我的条件。如果我删除条件,它会抛出索引越界异常。如果我有消息框,它会在消息框之前显示 0 个子项,在消息框之后显示 2 个(这与我的测试数据是正确的)子项,并且该方法的其余部分继续执行并完全按照我的意愿执行。

我可以做些什么(消息框除外)来正确遍历树?或者,最好是,是否有更简单的方法可以直接进入我想要操作的单元格?如果我可以选择 DataGridViewer 而不是 DataGrid,这似乎会很简单。

谢谢, 埃里克

P.S。 Whosebug 上回答了几个非常相似的问题,但每个问题似乎都在解决不同的问题 How can I access the data object of a DataGridCell in code? - 希望在删除后提取信息,我希望找到基于行和列的单元格,而不是任何类型的事件 Access to cell values of a DataGrid in WPF? - 是单元格值的一个很好的循环,但我似乎没有看到如何使用该过程来更改单元格属性(例如,如果单元格内容是 "Smith" 将字体更改为粗体)

这是我所做的...

// finds and returns a List<DependencyObject> containing datagrid row and cell based on sent datagrid, column, and row parameters
private List<DependencyObject> Get_DataGridCell_By_Index(DataGrid dataGrid, int row, int column)
{
    bool isFound = false;
    DataGridCell returnRow = new DataGridCell();
    DependencyObject returnCell = new DependencyObject();
    DependencyObject dependencyObject = dataGrid as DependencyObject;
    List<DependencyObject> returnList = new List<DependencyObject>();

    // to delete
    int dependencyObjectChildrenCount;
    // to delete

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
    {
        if (VisualTreeHelper.GetChild(dependencyObject, i) is Border)
        {
            dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
            isFound = true;
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is ScrollViewer)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is Grid)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is ScrollContentPresenter)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is ItemsPresenter)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    // to delete
    dependencyObjectChildrenCount = VisualTreeHelper.GetChildrenCount(dependencyObject);
    // to delete

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is DataGridRowsPresenter)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    // to delete
    dependencyObjectChildrenCount = VisualTreeHelper.GetChildrenCount(dependencyObject);
    // to delete

    // to delete
    // These are variation that I tried to determine what was causing/allowing the children count to go from 0 to the correct number
    //MessageBox.Show("isFound: " + isFound + "\n" + dependencyObject.ToString() + "\nrow: " + row + "\nRowPresenterCount: " + VisualTreeHelper.GetChildrenCount(dependencyObject));
    MessageBox.Show("");
    //dependencyObject.ToString();
    //VisualTreeHelper.GetChildrenCount(dependencyObject);
    // to delete

    // to delete
    dependencyObjectChildrenCount = VisualTreeHelper.GetChildrenCount(dependencyObject);
    // to delete

    if (isFound)
    {
        isFound = false;
        if (VisualTreeHelper.GetChildrenCount(dependencyObject) > row)
        {
            dependencyObject = VisualTreeHelper.GetChild(dependencyObject, row);
            if (dependencyObject is DataGridRow)
            {
                returnList.Add(dependencyObject);
                isFound = true;
            }
        }
    }

    // to delete
    dependencyObjectChildrenCount = VisualTreeHelper.GetChildrenCount(dependencyObject);
    // to delete

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is Border)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is SelectiveScrollingGrid)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is DataGridCellsPresenter)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is ItemsPresenter)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is DataGridCellsPanel)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        isFound = false;
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject) && !isFound; i++)
        {
            if (VisualTreeHelper.GetChild(dependencyObject, i) is DataGridCell)
            {
                dependencyObject = VisualTreeHelper.GetChild(dependencyObject, i);
                isFound = true;
            }
        }
    }

    if (isFound)
    {
        dependencyObject = Get_DataGrid_Sibling_Cell((DataGridCell)dependencyObject, column) as DependencyObject;
        if (dependencyObject != null)
        {
            returnList.Add(dependencyObject);
        }
    }

    return returnList;

} // end Get_DataGridCell_By_Index()

我也试过这个来获取行,但是我得到了一个空结果

DataGridRow row = vasgCategoryDataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;

您可以尝试这样的操作(除非您不使用 DataGridView): 希望对您有所帮助。

class Bar
{
    public static void Main(string[] args)
    {
        TestWindow Window = new TestWindow(800, 600);
        Window.ShowDialog();
    }
}

class TestWindow : Form
{
    public TestWindow(int Width, int Height)
    {
        Size = new Size(Width, Height);
        BackColor = Color.Black;
        ShowIcon = false;

        MaximizeBox = false;
        MinimizeBox = false;

        FormBorderStyle = FormBorderStyle.FixedSingle;

        MyDataGrid = new DataGrid();
        MyDataGrid.Size = new Size(400, 200);
        MyDataGrid.DataSource = new List<DummyData> { new DummyData("AB", "AD", "AI"), new DummyData("XB", "XS", "XI"), new DummyData("UUU", "FFF", "DDD"), new DummyData("XXXX", "UUUU", "IIII") };

        Button ShowCellButton = new Button();
        ShowCellButton.Click += new EventHandler(MyButton_Click);
        ShowCellButton.Location = new Point(700, 100);
        ShowCellButton.Text = "Show Text";
        ShowCellButton.ForeColor = Color.White;
        ShowCellButton.FlatStyle = FlatStyle.Flat;

        Controls.Add(MyDataGrid);
        Controls.Add(ShowCellButton);
    }

    DataGrid MyDataGrid;

    public void MyButton_Click(object sender, EventArgs e)
    {
        string Text = GetCellText(ref MyDataGrid, 2, 3); // Get Text in Column 2 and Row 3
        MessageBox.Show(Text.ToString());
    }

    public struct DummyData
    {
        public DummyData(string _Key, string _Value, string _Pair)
        {
            Key = _Key;
            Value = _Value;
            Pair = _Pair;
        }

        public string this[int Index]
        {
            get
            {
                if (Index == 0)
                    return Key;
                if (Index == 1)
                    return Value;
                if (Index == 2)
                    return Pair;
                return "";
            }
            set
            {
                if (Index == 0)
                    Key = value;
                if (Index == 1)
                    Value = value;
                if (Index == 2)
                    Pair = value;

            }
        }

        public string Key { get; set; }
        public string Value { get; set; }
        public string Pair { get; set; }
    }

    private string GetCellText(ref DataGrid MyDataGrid, int Column, int Row)
    {
        List<DummyData> MyData = (List<DummyData>)MyDataGrid.DataSource;

        string ReturnValue = "";

        for (int i = 0; i < MyData.ToArray().Length; i++)
        {
            DummyData Temp = MyData[Row - 1];
            return (Temp[Column - 1]);
        }

        return (ReturnValue);
    }
}

我能够在以下位置找到解决方案: https://social.msdn.microsoft.com/Forums/vstudio/en-US/0d7df388-da85-4c29-a425-925d13b17604/how-to-change-wpf-datagrid-cell-background-color-programmatically-using-c?forum=wpf

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace SelectDataGridCell
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            DataGridCell cell = GetCell(1, 1, myDataGrid);
                    cell.Background = new SolidColorBrush(Colors.Red);
        }

        public DataGridCell GetCell(int rowIndex, int columnIndex, DataGrid dg)
        {
            DataGridRow row = dg.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
            DataGridCellsPresenter p = GetVisualChild<DataGridCellsPresenter>(row);
            DataGridCell cell = p.ItemContainerGenerator.ContainerFromIndex(columnIndex) as DataGridCell;
            return cell;
        }

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