我发现的一种解决方法是设置按钮的宽度,该按钮位于行和列的交叉点(数据网格的左上角)。当第一行添加到数据网格时,此按钮会出现在可视树中。我在这里了解了这个按钮。
public MainWindow()
{
InitializeComponent();
myDataGrid.ItemContainerGenerator.StatusChanged += onItemContainerGeneratorStatusChanged;
}
private void onItemContainerGeneratorStatusChanged(object sender, EventArgs e)
{
if (((ItemContainerGenerator)sender).Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
Button btn = GetVisualChild<Button>(myDataGrid);
if (btn != null)
{
btn.Width = myDataGrid.RowHeaderActualWidth;
}
}
}
public 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;
}
但是,如果我将 DataGrid.RowDetailsTemplate 和 DataGrid.SelectedItem 设置为新添加的行,它就不起作用了。所以我尝试了以下方法:
private void onItemContainerGeneratorStatusChanged(object sender, EventArgs e)
{
if (((ItemContainerGenerator)sender).Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
{
ScrollViewer sv = GetVisualChild<ScrollViewer>(myDataGrid);
if (sv != null)
{
AutomationPeer automationPeer = FrameworkElementAutomationPeer.FromElement(sv);
if (automationPeer == null)
automationPeer = FrameworkElementAutomationPeer.CreatePeerForElement(sv);
IScrollProvider provider = automationPeer.GetPattern(PatternInterface.Scroll) as IScrollProvider;
try { provider.Scroll(ScrollAmount.SmallIncrement, ScrollAmount.NoAmount); }
catch { }
try { provider.Scroll(ScrollAmount.SmallDecrement, ScrollAmount.NoAmount); }
catch { }
}
}
}
这确实解决了最初的问题,但引入了一个新问题:验证错误红色框现在从它们指示的错误的文本框中移动。