Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Microsoft.Toolkit.Uwp.SampleApp/Data/DataGridDataItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ public string Parent_mountain
// You need to use DateTimeOffset to get proper binding to the CalendarDatePicker control, DateTime won't work.
public DateTimeOffset First_ascent { get; set; }

public bool IsFavorite { get; set; }

public string Ascents { get; set; }

bool INotifyDataErrorInfo.HasErrors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
<controls:DataGridTextColumn Header="Rank" Binding="{Binding Rank}" Tag="Rank" />
<controls:DataGridComboBoxColumn Header="Mountain" Binding="{Binding Mountain}" Tag="Mountain" />
<controls:DataGridTextColumn Header="Height (m)" Binding="{Binding Height_m}" Tag="Height_m" />
<controls:DataGridCheckBoxColumn Header="Favorite status" Binding="{Binding IsFavorite, Mode=TwoWay}" />
<controls:DataGridTextColumn Header="Range" Binding="{Binding Range}" Tag="Range" />
<controls:DataGridTextColumn Header="Parent Mountain" Binding="{Binding Parent_mountain}" Tag="Parent_mountain" />
<controls:DataGridTemplateColumn Header="First Ascent" Tag="First_ascent">
Expand Down
95 changes: 53 additions & 42 deletions Microsoft.Toolkit.Uwp.UI.Controls.DataGrid/DataGrid/DataGrid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5727,28 +5727,51 @@ private void DataGrid_LostFocus(object sender, RoutedEventArgs e)
_focusedObject = null;
if (this.ContainsFocus)
{
bool focusLeftDataGrid = true;
bool dataGridWillReceiveRoutedEvent = true;
DataGridColumn editingColumn = null;

// Walk up the visual tree of the newly focused element
// to determine if focus is still within DataGrid.
object focusedObject = GetFocusedElement();
DependencyObject focusedDependencyObject = focusedObject as DependencyObject;

while (focusedDependencyObject != null)
// Interacting with a Popup should never cause
// DataGrid to commit row/cell edits
bool focusLeftDataGrid = focusedDependencyObject is not Popup;
bool editingElementFocused = false;

if (this.EditingRow != null && this.EditingColumnIndex != -1)
{
var editingColumn = this.ColumnsItemsInternal[this.EditingColumnIndex];
var editingElement = editingColumn.GetCellContent(this.EditingRow);

// Handle weird scenario for ComboBox and other ItemsControls
// that don't work with DependencyObject.ContainsChild( )
if (editingElement is not ItemsControl ic)
{
editingElementFocused = editingElement.ContainsChild(focusedDependencyObject);
}
else
{
editingElementFocused = ic.ItemsPanelRoot.ContainsChild(focusedDependencyObject);
}

if (editingElement == focusedDependencyObject)
{
focusLeftDataGrid = false;
}
}

// Walk up the visual tree of the newly focused element
// to determine if focus is still within DataGrid.
while (focusedDependencyObject != null && focusedDependencyObject is not Popup && focusLeftDataGrid && !editingElementFocused)
{
if (focusedDependencyObject == this)
{
focusLeftDataGrid = false;
break;
}

// Walk up the visual tree. Try using the framework element's
// parent. We do this because Popups behave differently with respect to the visual tree,
// and it could have a parent even if the VisualTreeHelper doesn't find it.
DependencyObject parent = null;
FrameworkElement element = focusedDependencyObject as FrameworkElement;

// Walk up the visual tree. Try using the framework element's
// parent.
DependencyObject parent;
if (element == null)
{
parent = VisualTreeHelper.GetParent(focusedDependencyObject);
Expand All @@ -5760,32 +5783,19 @@ private void DataGrid_LostFocus(object sender, RoutedEventArgs e)
{
parent = VisualTreeHelper.GetParent(focusedDependencyObject);
}
else
{
dataGridWillReceiveRoutedEvent = false;
}
}

focusedDependencyObject = parent;
}

if (this.EditingRow != null && this.EditingColumnIndex != -1)
if (editingElementFocused)
{
editingColumn = this.ColumnsItemsInternal[this.EditingColumnIndex];

if (focusLeftDataGrid && editingColumn is DataGridTemplateColumn)
{
dataGridWillReceiveRoutedEvent = false;
}
HandleLostFocusForExternalElement(focusedObject);
}

if (focusLeftDataGrid && !(editingColumn is DataGridTemplateColumn))
else if (focusLeftDataGrid)
{
this.ContainsFocus = false;
if (this.EditingRow != null)
{
CommitEdit(DataGridEditingUnit.Row, true /*exitEditingMode*/);
}
CommitEdit(DataGridEditingUnit.Row, true /*exitEditingMode*/);

ResetFocusedRow();
ApplyDisplayedRowsState(this.DisplayData.FirstScrollingSlot, this.DisplayData.LastScrollingSlot);
Expand All @@ -5798,14 +5808,15 @@ private void DataGrid_LostFocus(object sender, RoutedEventArgs e)
UpdateCurrentState(this.DisplayData.GetDisplayedElement(this.CurrentSlot), this.CurrentColumnIndex, true /*applyCellState*/);
}
}
else if (!dataGridWillReceiveRoutedEvent)
{
FrameworkElement focusedElement = focusedObject as FrameworkElement;
if (focusedElement != null)
{
focusedElement.LostFocus += new RoutedEventHandler(ExternalEditingElement_LostFocus);
}
}
}
}

private void HandleLostFocusForExternalElement(object focusedObject)
{
FrameworkElement focusedElement = focusedObject as FrameworkElement;
if (focusedElement != null)
{
focusedElement.LostFocus += new RoutedEventHandler(ExternalEditingElement_LostFocus);
}
}

Expand Down Expand Up @@ -8643,12 +8654,6 @@ private bool UpdateStateOnTapped(TappedRoutedEventArgs args, int columnIndex, in
{
_noSelectionChangeCount++;

beginEdit = allowEdit &&
this.CurrentSlot == slot &&
columnIndex != -1 &&
(wasInEdit || this.CurrentColumnIndex == columnIndex) &&
!GetColumnEffectiveReadOnlyState(this.ColumnsItemsInternal[columnIndex]);

DataGridSelectionAction action;
if (this.SelectionMode == DataGridSelectionMode.Extended && shift)
{
Expand Down Expand Up @@ -8687,6 +8692,12 @@ private bool UpdateStateOnTapped(TappedRoutedEventArgs args, int columnIndex, in
}

UpdateSelectionAndCurrency(columnIndex, slot, action, false /*scrollIntoView*/);

beginEdit = allowEdit &&
this.CurrentSlot == slot &&
columnIndex != -1 &&
(wasInEdit || this.CurrentColumnIndex == columnIndex) &&
!GetColumnEffectiveReadOnlyState(this.ColumnsItemsInternal[columnIndex]);
}
finally
{
Expand Down